Aaron S. Hawley: changed files.texi building.texi custom.texi files.el
glossary.texi isearch.el misc.texi
-Abraham Nahum: changed configure.in dgux4.h sysdep.c
+Abraham Nahum: changed dgux4.h sysdep.c
Abramo Bagnara: changed term.c
+Adam Go\e,B3j\e(Bbiowski: changed Makefile.in
+
Adam Hupp: changed gdb-ui.el
Adrian Aichner: changed erc-log.el erc.el erc-autojoin.el erc-backend.el
erc-dcc.el erc-members.el erc-nets.el erc-sound.el etags.c
- gnus-score.el
+ gnus-score.el gnus-sum.el gnus.texi
Adrian Colley: changed aix3-2.h
Agust\e,Am\e(Bn Mart\e,Am\e(Bn: changed flyspell.el ispell.el
-Aidan Kehoe: changed lread.c mm-util.el erc.el latin-ltx.el objects.texi
+Aidan Kehoe: changed lread.c mm-util.el erc.el gnus-sum.el gnus-util.el
+ latin-ltx.el objects.texi
Ake Stenhoff: wrote imenu.el
and changed cc-mode.el perl-mode.el
Alan Mackenzie: wrote cc-awk.el
and changed cc-cmds.el cc-mode.el cc-engine.el cc-defs.el cc-langs.el
cc-vars.el cc-mode.texi cc-styles.el cc-fonts.el cc-align.el lread.c
- programs.texi cc-subword.el isearch.el lisp.el search.texi startup.el
- subr.el text.texi buffers.texi bytecomp.el and 20 other files
+ programs.texi cc-subword.el font-lock.el isearch.el lisp.el search.texi
+ startup.el subr.el text.texi add-log.el and 21 other files
Alan Shutko: changed diary-lib.el calendar.el bindings.el cal-hebrew.el
easy-mmode.el gnus-sum.el ibuf-ext.el ibuffer.el lunar.el macros.el
Alexandre Julliard: wrote vc-git.el
Alexandre Oliva: wrote gnus-mlspl.el
-and changed unexelf.c format.el iris4d.h iris5d.h unexsgi.c
+and changed unexelf.c format.el iris4d.h iris5d.h regex.c unexsgi.c
Alexandre Veyrenc: changed fr-refcard.tex
Alin C. Soare: changed lisp-mode.el hexl.el
-Ami Fischman: changed calendar.el diary-lib.el
+Ami Fischman: changed calendar.el diary-lib.el print.c
Anders Holst: wrote hippie-exp.el
Andreas Luik: changed xfns.c xterm.c
Andreas Schwab: changed Makefile.in files.el lisp.h alloc.c xdisp.c
- configure.in editfns.c fns.c print.c coding.c dired.el fileio.c info.el
- eval.c process.c simple.el buffer.c minibuf.c window.c xterm.c emacs.c
- and 452 other files
+ editfns.c print.c fns.c coding.c dired.el fileio.c info.el eval.c
+ process.c simple.el buffer.c minibuf.c window.c xterm.c emacs.c
+ keyboard.c and 452 other files
Andreas Seltenreich: changed nnweb.el gnus.texi nnslashdot.el
gnus-util.el mm-uu.el url-http.el battery.el comint.el easy-mmode.el
and changed macterm.c mac.c macfns.c INSTALL macmenu.c darwin.h macterm.h
sysdep.c emacs.c fontset.c frame.c keyboard.c macgui.h xfaces.c Emacs.r
README cw5-mcp.xml cw6-mcp.xml dispextern.h make-package makefile.MPW
- and 61 other files
+ and 60 other files
Andrew Cohen: changed dns.el
Barry Fishman: changed gnu-linux.h
-Ben A. Mesander: wrote erc-dcc.el
+Bastien Guerry: wrote org-export-latex.el
-Ben Harris: changed configure.in
+Ben A. Mesander: wrote erc-dcc.el
Ben Key: changed w32.c w32fns.c w32menu.c makefile.w32-in w32.h w32term.c
emacs.c gmake.defs ms-w32.h nmake.defs sound.c
Bill Carpenter: wrote feedmail.el (public domain)
-Bill Mann: changed configure.in unexaix.c ibmrs6000.h usg5-4-3.h
+Bill Mann: changed unexaix.c ibmrs6000.h usg5-4-3.h
Bill Meier: changed sh-script.el
Boris Samorodov: changed imap.el
-Boyd Lynn Gerber: changed configure.in
-
Brad Howes: changed gnus-demon.el
Brad Miller: wrote gnus-gl.el
Brian D. Carlstrom: changed gud.el smtpmail.el
-Brian Fox: changed Makefile.in configure.in minibuf.c dired.el files.el
- rmail.el search.c simple.el sysdep.c Makefile compile.el forms.texi
- frame.c info.texi keyboard.c make-dist subr.el systty.h xterm.c INSTALL
- alloc.c and 44 other files
+Brian Fox: changed Makefile.in minibuf.c dired.el files.el rmail.el
+ search.c simple.el sysdep.c Makefile compile.el forms.texi frame.c
+ info.texi keyboard.c make-dist subr.el systty.h xterm.c INSTALL alloc.c
+ alloca.c and 43 other files
Brian Marick: wrote hideif.el
and changed org.texi orgcard.tex idlw-shell.el idlwave.el idlw-rinfo.el
reftex.texi reftex-vcr.el diary-lib.el bibtex.el bookmark.el files.el
idlwave-rinfo.el idlwave-shell.el idlwave-toolbar.el
+ org-export-latex.el org-irc.el org-mac-message.el org-publish.el
-Caveh Jalali: changed configure.in intel386.h sol2-4.h
+Caveh Jalali: changed intel386.h sol2-4.h
Changwoo Ryu: changed files.el
Chao-Hong Liu: changed TUTORIAL.cn TUTORIAL.zh
-Charles Hannum: changed aix3-1.h aix3-2.h configure ibmrs6000.h
- keyboard.c netbsd.h pop.c sysdep.c systime.h systty.h xrdb.c
+Charles Hannum: changed aix3-1.h aix3-2.h ibmrs6000.h keyboard.c netbsd.h
+ pop.c sysdep.c systime.h systty.h xrdb.c
Charlie Martin: wrote autoinsert.el
Cheng Gao: changed MORE.STUFF flymake.el tips.texi url-dired.el
url-file.el url-handlers.el url-http.el url-nfs.el
-Chong Yidong: changed files.el simple.el cus-edit.el xdisp.c longlines.el
+Chong Yidong: changed xdisp.c files.el simple.el cus-edit.el longlines.el
display.texi custom.el files.texi image-mode.el keyboard.c info.el
- compile.el custom.texi text.texi xterm.c frames.texi image.c mouse.el
- misc.texi startup.el wid-edit.el and 322 other files
+ compile.el custom.texi image.c text.texi xterm.c frames.texi mouse.el
+ misc.texi startup.el wid-edit.el and 331 other files
Chris Hanson: changed xscheme.el scheme.el xterm.c hpux.h x11term.c
hp9000s300.h keyboard.c process.c texinfmt.el emacsclient.c sort.el
Chris Smith: wrote icon.el
and changed icon-mode.el
-Christian Limpach: changed configure.in
-
Christian Lynbech: changed appt.el emacsserver.c
Christian Neukirchen: changed mm-util.el
Christian Von Roques: changed gnus-start.el
-Christoph Bauer: changed configure.in
-
Christoph Conrad: changed gnus-agent.el gnus-score.el makefile.w32-in
qp.el
calc-misc.el Makefile.in calc-macs.el calc-mode.el calc-graph.el
gamegrid.el calc-aent.el calc-bin.el calc-embed.el calc-keypd.el
calc-math.el calc-prog.el calc-units.el calcalg2.el font-core.el
- info.el calc-alg.el and 78 other files
+ info.el calc-alg.el and 77 other files
Craig Mcdaniel: changed sheap.c
and changed xterm.el term.el hideshow.el vc-hg.el verilog-mode.el
files.el isearch.el sh-script.el font-lock.el icon.el lisp.h vc.el
cus-edit.el faces.el grep.el diff-mode.el eterm-color.ti ibuffer.el
- replace.el rxvt.el term.c and 192 other files
+ replace.el rxvt.el term.c and 190 other files
Daniel Brockman: changed cus-start.el format-spec.el ibuffer.el rcirc.el
smiley.el subst-big5.el subst-gb2312.el subst-jis.el subst-ksc.el
tool-bar.el ucs-tables.el uni-input.el utf-16.el utf-7.el utf-8-lang.el
vc-bzr.el welsh.el
-and changed configure.in Makefile.in help.el fortran.el browse-url.el
- mule-cmds.el simple.el xterm.c cus-edit.el files.el info.el mule.el
- wid-edit.el fns.c vc.el rfc2047.el bindings.el cus-start.el buffer.c
- byte-opt.el bytecomp.el and 727 other files
+and changed Makefile.in help.el fortran.el browse-url.el mule-cmds.el
+ simple.el xterm.c cus-edit.el files.el info.el mule.el wid-edit.el
+ fns.c vc.el rfc2047.el bindings.el cus-start.el buffer.c byte-opt.el
+ bytecomp.el config.in and 726 other files
Dave Pearson: wrote 5x5.el quickurl.el
message.el mm-encode.el mm-util.el nndoc.el nnmail.el score-mode.el
webmail.el
+David Hull: changed vc-hg.el
+
David Hunter: changed config.nt flymake.el ms-w32.h process.c
-David J. Mackenzie: changed configure.in etags.c fakemail.c movemail.c
- wakeup.c Makefile cvtmail.c qsort.c termcap.c yow.c Makefile.in
- avoid.el b2m.c digest-doc.c emacsclient.c emacsserver.c emacstool.c
- etags-vmslib.c fortran.el hexl.c isearch.el and 12 other files
+David J. Mackenzie: changed etags.c fakemail.c movemail.c wakeup.c
+ Makefile cvtmail.c qsort.c termcap.c yow.c Makefile.in avoid.el b2m.c
+ digest-doc.c emacsclient.c emacsserver.c emacstool.c etags-vmslib.c
+ fortran.el hexl.c isearch.el make-docfile.c and 11 other files
David Kastrup: changed greek.el replace.el faq.texi search.c ange-ftp.el
help.el mouse.el Makefile.in calc.el desktop.el keymaps.texi
meta-mode.el process.c search.texi subr.el woman.el DEBUG DEVEL.HUMOR
- MAILINGLISTS advice.el autoload.el and 40 other files
+ MAILINGLISTS advice.el autoload.el and 39 other files
David K\e,Ae\e(Bgedal: wrote tempo.el
and changed sendmail.el xmenu.c
David Moore: wrote nnvirtual.el
and changed gnus-xmas.el
-David Mosberger-Tang: changed alpha.h unexelf.c cm.h config.in
- configure.in cvtmail.c data.c dispnew.c emacsserver.c etags.c
- fakemail.c keyboard.c mem-limits.h process.c profile.c sorted-doc.c
- sysdep.c terminfo.c unexelf1.c yow.c
+David Mosberger-Tang: changed alpha.h unexelf.c cm.h config.in cvtmail.c
+ data.c dispnew.c emacsserver.c etags.c fakemail.c keyboard.c
+ mem-limits.h process.c profile.c sorted-doc.c sysdep.c terminfo.c
+ unexelf1.c yow.c
+
+David O'Toole: wrote org-publish.el
David Ponce: wrote recentf.el ruler-mode.el tree-widget.el
and changed w32menu.c w32term.c close.png close.xpm empty.png empty.xpm
emacsclient.c keymap.c macterm.c menu-bar.el minibuf.c python.el
sendmail.el url-http.el
+David Robinow: changed w32inevt.c
+
David Robinson: changed menu-bar.el x-win.el
David S. Goldberg: changed gnus-art.el message.el
Davis Herring: changed desktop.el timeclock.el
-Deanna Phillips: changed configure.in
-
Decklin Foster: changed nngateway.el
Deepak Goel: changed README ada-mode.el ada-xref.el appt.el apropos.el
Denis St\e,A|\e(Bnkel: changed ibuf-ext.el
+Dennis Gilmore: changed sparc.h
+
Derek Atkins: changed imap.el pgg-pgp.el
Derek L. Davies: changed gud.el
Edwin Steiner: changed gnus-nocem.el
Ehud Karni: changed rmail.el aviion-intel.h compile.el complete.el
- configure.in frame.el rmailsum.el sort.el xdisp.c
+ frame.el rmailsum.el sort.el xdisp.c
Eirik Fuller: changed ralloc.c xterm.c
and changed msdos.c Makefile.in makefile.w32-in files.el info.el fileio.c
startup.el mainmake.v2 rmail.el config.bat menu-bar.el simple.el
pc-win.el msdos.h internal.el xfaces.c emacs.c frame.c INSTALL dosfns.c
- mule-cmds.el and 537 other files
+ mule-cmds.el and 535 other files
-Emanuele Giaquinta: changed rxvt.el configure.in etags.c frame.el
- gnus-faq.texi sh-script.el text.texi
+Emanuele Giaquinta: changed rxvt.el etags.c frame.el gnus-faq.texi
+ sh-script.el text.texi
Emilio C. Lopes: changed woman.el cmuscheme.el help.el vc.el advice.el
animate.el apropos.el artist.el bookmark.el cal-menu.el calc-prog.el
and changed ada-mode.el ada-stmt.el ada-xref.el
Enami Tsugutomo: changed frame.c keyboard.c dispnew.c fileio.c process.c
- xdisp.c add-log.el bytecomp.el configure.in editfns.c emacs.c frame.h
- gnus-group.el perl-mode.el rmailsum.el simple.el sysdep.c vc.el
- window.c window.el
+ xdisp.c add-log.el bytecomp.el editfns.c emacs.c frame.h gnus-group.el
+ perl-mode.el rmailsum.el simple.el sysdep.c vc.el window.c window.el
Era Eriksson: changed dired.el shell.el
Erik Naggum: wrote disp-table.el latin-4.el latin-5.el mailheader.el
parse-time.el
and changed simple.el emacs.c files.el lread.c rmail.el alloc.c editfns.c
- keyboard.c apropos.el configure.in dispnew.c filelock.c fns.c keymap.c
- lisp.h print.c process.c add-log.el buffer.c casetab.c cl-macs.el
- and 112 other files
+ keyboard.c apropos.el dispnew.c filelock.c fns.c keymap.c lisp.h
+ print.c process.c add-log.el buffer.c casetab.c cl-macs.el comint.el
+ and 111 other files
Erik Toubro Nielsen: changed gnus-sum.el gnus-topic.el
Francesco Potort\e,Al\e(B: wrote cmacexp.el
and changed etags.c man.el delta.h etags.1 undigest.el comint.el
- configure.in maintaining.texi uniquify.el latin-post.el rmail.el
- Makefile.in etags.el latin-alt.el sgml-mode.el data.c european.el
- filelock.c files.el generic-x.el gud.el and 44 other files
+ maintaining.texi uniquify.el latin-post.el rmail.el Makefile.in
+ etags.el latin-alt.el sgml-mode.el data.c european.el filelock.c
+ files.el generic-x.el gud.el hanoi.el and 43 other files
Francis J. Wright: wrote woman.el
and changed dired.el comint.el files.el
Frank Bresz: wrote diff.el
-Frank Schmitt: changed gnus-sum.el gnus-util.el
+Frank Schmitt: changed gnus-sum.el gnus-faq.texi gnus-util.el
Frank Weinberg: changed gnus-art.el
Frederic Pierresteguy: wrote widget.c
and changed xmenu.c xterm.c xfns.c dpx2.h lwlib.c rmailsum.el rmail.el
- xlwmenu.c xterm.h lwlib-Xaw.c lwlib-Xlw.c Makefile.in configure.in
- lwlib-Xaw.h lwlib-int.h xdisp.c compile.el editfns.c fns.c frame.h
- hilit19.el and 9 other files
+ xlwmenu.c xterm.h lwlib-Xaw.c lwlib-Xlw.c Makefile.in lwlib-Xaw.h
+ lwlib-int.h xdisp.c compile.el editfns.c fns.c frame.h hilit19.el
+ keyboard.c and 8 other files
Frederik Fouvry: changed sendmail.el TUTORIAL.nl emacs.bash faces.el
filecache.el mailalias.el rmail.el thumbs.el
Gerd M\e,Av\e(Bllmann: wrote authors.el ebrowse.el jit-lock.el rx.el tooltip.el
and changed xdisp.c xterm.c dispnew.c dispextern.h xfns.c xfaces.c
window.c keyboard.c lisp.h Makefile.in faces.el alloc.c buffer.c
- startup.el xterm.h fns.c simple.el term.c configure.in frame.c xmenu.c
- and 620 other files
+ startup.el xterm.h fns.c simple.el term.c frame.c xmenu.c emacs.c
+ and 618 other files
Gergely Nagy: changed erc.el
Gernot Heiser: changed refer.el
-Giorgos Keramidas: changed configure.in MACHINES amdx86-64.h apropos.el
- display.texi fringe.c fringe.el lisp.h windows.texi xmenu.c
+Giorgos Keramidas: changed MACHINES amdx86-64.h apropos.el display.texi
+ fringe.c fringe.el lisp.h windows.texi xmenu.c
-Giuseppe Scrivano: changed buffer.c configure.in sysdep.c xsmfns.c
+Giuseppe Scrivano: changed buffer.c sysdep.c xsmfns.c
Glenn Morris: changed f90.el diary-lib.el calendar.el fortran.el
calendar.texi COPYING appt.el Makefile.in files.el sh-script.el
- timeclock.el cal-menu.el configure.in simple.el tex-mode.el calc.texi
- complete.el fr-refcard.tex orgcard.tex programs.texi startup.el
- and 250 other files
+ simple.el timeclock.el cal-menu.el tex-mode.el cal-islam.el cal-tex.el
+ calc.texi complete.el fr-refcard.tex holidays.el orgcard.tex
+ and 260 other files
Glynn Clements: wrote gamegrid.el snake.el tetris.el
Greg Hill: changed bytecomp.el
-Greg Hudson: changed configure.in indent.c
+Greg Hudson: changed indent.c
Greg Klanderman: changed messagexmas.el
Ishikawa Chiaki: changed aviion.h dgux.h
+\e$,1 P\e(Bsmail D\e,Av\e(Bnmez: changed xterm.c
+
Istvan Marko: changed gnus-agent.el xfns.c
Itai Zukerman: changed mm-decode.el
and changed bytecode.c mail-extr.el subr.el
Jan Dj\e,Ad\e(Brv: wrote dnd.el x-dnd.el
-and changed gtkutil.c xterm.c xfns.c xmenu.c xterm.h configure.in
- x-win.el gtkutil.h keyboard.c Makefile.in frames.texi config.in
- xselect.c emacs.c alloc.c xlwmenu.c xresources.texi startup.el frame.c
- xdisp.c xfaces.c and 177 other files
+and changed gtkutil.c xterm.c xfns.c xmenu.c xterm.h x-win.el gtkutil.h
+ keyboard.c Makefile.in frames.texi config.in xselect.c emacs.c alloc.c
+ xlwmenu.c xresources.texi startup.el frame.c xdisp.c xfaces.c
+ cus-start.el and 175 other files
Jan Nieuwenhuizen: changed info.el TUTORIAL.nl emacs.c emacsclient.c
gnus-start.el gud.el nnmh.el server.el startup.el
Jari Aalto: changed add-log.el filecache.el gnus-art.el lisp-mnt.el
man.el nnmail.el apropos.el autorevert.el comint.el compile.el
- cperl-mode.el debug.el executable.el files.el finder.el font-lock.el
- gnus.el gnus.texi grep.el ls-lisp.el sendmail.el terminal.el
+ cperl-mode.el debug.el executable.el files.el find-dired.el finder.el
+ font-lock.el gnus.el gnus.texi grep.el ls-lisp.el and 3 other files
Jason Merrill: changed gnus-sum.el gnus-salt.el imap.el nnfolder.el
Jason Rumney: wrote w32-vars.el
-and changed w32fns.c w32term.c w32menu.c w32-win.el makefile.w32-in
+and changed w32fns.c w32term.c w32menu.c makefile.w32-in w32-win.el
w32term.h w32.c w32bdf.c w32-fns.el w32proc.c w32select.c w32console.c
- mule-cmds.el w32gui.h keyboard.c emacs.c fileio.c files.el nmake.defs
- w32bdf.h w32inevt.c and 94 other files
+ mule-cmds.el w32gui.h image.c keyboard.c emacs.c fileio.c files.el
+ nmake.defs w32bdf.h and 97 other files
Jay Belanger: changed calc.texi calc.el calc-ext.el calc-embed.el
calc-aent.el calc-prog.el calc-arith.el calc-help.el calc-lang.el
- calcalg2.el COPYING calc-graph.el calc-store.el calc-units.el
+ calc-units.el calcalg2.el COPYING calc-graph.el calc-store.el
calc-misc.el calc-yank.el calc-alg.el calc-poly.el calccomp.el
calc-mode.el calc-forms.el and 35 other files
Jens-Ulrik Holger Petersen: changed cus-edit.el find-func.el gnus.el
-Jeramey Crawford: changed amdx86-64.h configure.in
+Jeramey Crawford: changed amdx86-64.h
Jeremy Bertram Maitin-Shepard: changed erc.el erc-backend.el
erc-button.el mml.el
Jim Blandy: wrote tvi970.el
and changed keyboard.c xterm.c xfns.c Makefile.in window.c process.c
- dispnew.c xdisp.c sysdep.c configure.in lisp.h keymap.c configure
- make-dist buffer.c frame.c screen.c x-win.el simple.el alloc.c emacs.c
- and 389 other files
+ dispnew.c xdisp.c sysdep.c lisp.h keymap.c make-dist buffer.c frame.c
+ screen.c x-win.el simple.el alloc.c emacs.c fileio.c xfaces.c
+ and 388 other files
Jim Kingdon: changed MACHINES SERVICE emacsclient.c emacs.tex hp300bsd.h
rmail.el
Jirka Kosek: changed mule.el
+Joachim Nilsson: changed cc-styles.el
+
Joakim Hove: wrote html2text.el
Joakim Verona: changed nnrss.el
Jochen K\e,A|\e(Bpper: changed calc-units.el gnus.texi
-Joe Buehler: changed Makefile.in configure.in cygwin.h MACHINES
- browse-url.el comint.el configure dired-aux.el dired.el dirtrack.el
- dos-w32.el fast-lock.el filecache.el fileio.c files.el gmalloc.c
- gnus-util.el hippie-exp.el keyboard.c lastfile.c loadup.el
- and 12 other files
+Joe Buehler: changed Makefile.in cygwin.h MACHINES browse-url.el
+ comint.el dired-aux.el dired.el dirtrack.el dos-w32.el fast-lock.el
+ filecache.el fileio.c files.el gmalloc.c gnus-util.el hippie-exp.el
+ keyboard.c lastfile.c loadup.el mem-limits.h mule.el and 10 other files
Joe Casadonte: changed gnus-srvr.el
Joev Dubach: changed nntp.el
-Johan Bockg\e$: changed info.el
-
Johan Bockg\e,Ae\e(Brd: changed erc.el erc-backend.el cl-macs.el erc-match.el
custom.el erc-nickserv.el erc-ring.el erc-speak.el erc-track.el
simple.el subr.el xterm.el align.el browse-url.el bytecomp.el
calendar.el cl.texi dired-aux.el dired-x.el display.texi erc-bbdb.el
- and 23 other files
+ and 24 other files
Johan Vromans: wrote forms-d2.el forms.el iso-acc.el
and changed complete.el
em-term.el em-unix.el em-xtra.el erc-identd.el esh-arg.el esh-cmd.el
esh-ext.el esh-io.el esh-maint.el esh-mode.el esh-module.el esh-opt.el
esh-proc.el esh-test.el esh-util.el esh-var.el eshell.el eudcb-mab.el
- isearchb.el pcmpl-cvs.el pcomplete.el timeclock.el
-and changed erc-chess.el erc.el iswitchb.el Makefile.in allout.el
- cal-menu.el calendar.el compile.el desktop.el diary-lib.el erc-bbdb.el
- erc-button.el erc-complete.el erc-fill.el erc-ibuffer.el erc-list.el
- erc-match.el erc-menu.el erc-nets.el erc-replace.el erc-speak.el
+ isearchb.el org-mac-message.el pcmpl-cvs.el pcomplete.el timeclock.el
+and changed erc-chess.el erc.el iswitchb.el url-auth.el Makefile.in
+ allout.el cal-menu.el calendar.el compile.el desktop.el diary-lib.el
+ erc-bbdb.el erc-button.el erc-complete.el erc-fill.el erc-ibuffer.el
+ erc-list.el erc-match.el erc-menu.el erc-nets.el erc-replace.el
and 12 other files
John Williams: changed etags.el
Jon K Hellan: wrote utf7.el
-Jonathan I. Kamens: changed pop.c movemail.c rmail.el configure.in
- Makefile.in b2m.pl config.in files.el pop.h terminal.el vc.el
- gnus-sum.el jka-compr.el rmailout.el rnewspost.el sendmail.el simple.el
- timezone.el vc-hooks.el
+Jonathan I. Kamens: changed pop.c movemail.c rmail.el Makefile.in b2m.pl
+ config.in files.el pop.h terminal.el vc.el gnus-sum.el jka-compr.el
+ rmailout.el rnewspost.el sendmail.el simple.el timezone.el vc-hooks.el
Jonathan Stigelman: wrote hilit19.el
and changed files.el perl-mode.el
Juanma Barranquero: changed makefile.w32-in subr.el faces.el files.el
- help-fns.el bs.el w32fns.c buffer.c simple.el desktop.el emacsclient.c
- replace.el eval.c org.el idlwave.el ido.el process.c vhdl-mode.el
- window.c xdisp.c allout.el and 661 other files
+ help-fns.el bs.el w32fns.c buffer.c desktop.el simple.el emacsclient.c
+ replace.el eval.c org.el xdisp.c idlwave.el ido.el process.c
+ vhdl-mode.el window.c allout.el and 665 other files
Juergen Hoetzel: changed url-handlers.el
Justin Sheehy: changed gnus-sum.el nntp.el
-J\e,Ai\e(Br\e,At\e(Bme Marant: changed Makefile.in make-dist bindings.el configure.in
- emacsclient.c misc.texi
+J\e,Ai\e(Br\e,At\e(Bme Marant: changed Makefile.in make-dist bindings.el emacsclient.c
+ misc.texi
K. Shane Hartman: wrote chistory.el echistory.el electric.el emacsbug.el
helper.el picture.el view.el
and changed gnus-agent.el message.el gnus-sum.el files.el nnmail.el
tramp.texi gnus.el simple.el ange-ftp.el Makefile.in dired.el
paragraphs.el bindings.el files.texi gnus-art.el gnus-group.el man.el
- nntp.el INSTALL crisp.el fileio.c and 44 other files
+ nntp.el INSTALL crisp.el fileio.c and 43 other files
Kailash C. Chowksey: changed HELLO Makefile.in ind-util.el kannada.el
knd-util.el loadup.el makefile.w32-in
nnmail.el vc-svn.el window.c
Karl Heuer: changed keyboard.c lisp.h xdisp.c buffer.c xfns.c xterm.c
- alloc.c files.el frame.c configure.in window.c data.c minibuf.c
- editfns.c fns.c process.c fileio.c simple.el keymap.c indent.c sysdep.c
- and 444 other files
+ alloc.c files.el frame.c window.c data.c minibuf.c editfns.c fns.c
+ process.c fileio.c simple.el keymap.c indent.c sysdep.c lread.c
+ and 443 other files
Karl Kleinpaste: changed gnus-sum.el gnus-art.el gnus-picon.el
gnus-score.el gnus-uu.el gnus-xmas.el gnus.el mm-uu.el mml.el nnmail.el
and changed gnus-art.el message.el gnus-sum.el gnus.texi mm-decode.el
mm-view.el gnus-util.el gnus.el mm-util.el gnus-msg.el nntp.el
gnus-agent.el gnus-start.el lpath.el rfc2047.el gnus-group.el
- dgnushack.el mm-uu.el mml.el nnrss.el message.texi and 76 other files
+ dgnushack.el mm-uu.el mml.el nnrss.el message.texi and 77 other files
Kaveh R. Ghazi: changed delta88k.h xterm.c
Ken Raeburn: changed lisp.h buffer.c alloc.c keyboard.c lread.c minibuf.c
coding.c Makefile.in editfns.c fileio.c fns.c keymap.c undo.c xdisp.c
xfns.c xterm.c charset.h fontset.c search.c window.c charset.c
- and 84 other files
+ and 82 other files
Ken Stevens: wrote ispell.el
and changed coding.c mule-cmds.el mule.el charset.c fileio.c xterm.c
fns.c ccl.c Makefile.in mule-conf.el fontset.c charset.h coding.h
fontset.el mule-diag.el xdisp.c editfns.c process.c insdel.c
- japanese.el characters.el and 286 other files
+ japanese.el characters.el and 285 other files
-Kenneth Stailey: changed alpha.h configure.in ns32000.h openbsd.h pmax.h
- sparc.h unexalpha.c unexelf.c
+Kenneth Stailey: changed alpha.h ns32000.h openbsd.h pmax.h sparc.h
+ unexalpha.c unexelf.c
Kevin Blake: changed font-lock.el ring.el
Kevin Ryde: wrote info-xref.el
and changed info-look.el info.el mule.el arc-mode.el cl.texi gnus-art.el
- gnus-sum.el mailcap.el os.texi text.texi MORE.STUFF cal-dst.el
- calendar.texi cc-align.el cmdargs.texi compilation.txt compile.el
- compile.texi custom.texi display.texi em-alias.el and 22 other files
+ gnus-sum.el mailcap.el os.texi text.texi MORE.STUFF autoload.el
+ cal-dst.el calendar.texi cc-align.el cmdargs.texi compilation.txt
+ compile.el compile.texi custom.texi display.texi and 24 other files
Kim F. Storm: wrote bindat.el cua-base.el cua-gmrk.el cua-rect.el ido.el
keypad.el kmacro.el
and changed xdisp.c dispextern.h process.c simple.el window.c keyboard.c
xterm.c subr.el w32term.c dispnew.c lisp.h fringe.c macterm.c
display.texi fns.c alloc.c xfaces.c keymap.c xfns.c xterm.h .gdbinit
- and 255 other files
+ and 254 other files
Kim-Minh Kaplan: changed gnus-picon.el gnus-sum.el gnus-start.el
gnus-win.el gnus-xmas.el gnus.texi message.el nndraft.el nnml.el
Klaus Straubinger: changed url-http.el url-history.el url-cookie.el
url.el
-Klaus Zeitler: changed configure.in files.el sh-script.el vcursor.el
+Klaus Zeitler: changed files.el sh-script.el vcursor.el
Koaunghi Un: wrote hanja3.el
and changed hanja.el hangul.el hangul3.el hanja-jis.el symbol-ksc.el
Lars Balker Rasmussen: changed gnus-art.el gnus-agent.el message.el
-Lars Brinkhoff: changed building.texi config.in configure.in editfns.c
- fns.c os.texi
+Lars Brinkhoff: changed building.texi config.in editfns.c fns.c os.texi
Lars Hansen: changed desktop.el tramp.el info.el mh-e.el dired-x.el
dired-x.texi dired.el ls-lisp.el rmail.el dired.c files.texi grp.h
comint.el custom.texi emacs.texi fns.c frame.el ielm.el minibuf.texi
modes.texi variables.texi buffers.texi and 215 other files
+Luca Capello: changed mm-encode.el
+
Lucid, Inc.: changed byte-opt.el byte-run.el bytecode.c bytecomp.el
delsel.el disass.el faces.el font-lock.el lmenu.el lselect.el
mailabbrev.el select.el xfaces.c xselect.c
font-lock.el subr.el Makefile.in debugging.texi easy-mmode.el
elisp.texi hl-line.el simple.el battery.el bindings.el calc.el
cmdargs.texi edebug.texi emacs.texi info.el make-tarball.txt
- octave-inf.el and 216 other files
+ octave-inf.el and 215 other files
Lynn Slater: wrote help-macro.el
Marco Walther: changed mips-siemens.h unexelfsni.c unexsni.c
-Marcus G. Daniels: changed xterm.c configure.in lwlib-Xm.c lwlib.c
- Makefile.in xdisp.c xfns.c xmenu.c alloc.c config.in dispnew.c
- editfns.c emacs.c irix5-0.h linux.h lwlib-Xm.h lwlib.h ptx4.h
- sequent-ptx.h unexelf.c
+Marcus G. Daniels: changed xterm.c lwlib-Xm.c lwlib.c Makefile.in xdisp.c
+ xfns.c xmenu.c alloc.c config.in dispnew.c editfns.c emacs.c irix5-0.h
+ linux.h lwlib-Xm.h lwlib.h ptx4.h sequent-ptx.h unexelf.c
Marek Martin: changed nnfolder.el
mh-seq.el mh-speed.el mh-funcs.el mh-alias.el MH-E-NEWS etags.c
mh-junk.el mh-pick.el mh-tool-bar.el mh-xemacs-compat.el
-Mark Davies: changed Makefile.in amdx86-64.h configure configure.in
- hp800.h netbsd.h ralloc.c sh3el.h sort.el
+Mark Davies: changed Makefile.in amdx86-64.h hp800.h netbsd.h ralloc.c
+ sh3el.h sort.el
Mark Diekhans: changed compile.el
Markus Rost: wrote cus-test.el
and changed cus-edit.el Makefile.in files.el compile.el rmail.el
tex-mode.el find-func.el rmailsum.el simple.el cus-dep.el dired.el
- mule-cmds.el rmailout.el checkdoc.el configure.in custom.el emacsbug.el
- gnus.el help-fns.el ls-lisp.el mwheel.el and 122 other files
+ mule-cmds.el rmailout.el checkdoc.el custom.el emacsbug.el gnus.el
+ help-fns.el ls-lisp.el mwheel.el sendmail.el and 121 other files
Markus Triska: changed byte-opt.el bytecomp.el doctor.el expand.el
- flymake.el flymake.texi handwrite.el internals.texi speedbar.el subr.el
- tumme.el widget.texi
+ flymake.el flymake.texi handwrite.el image-mode.el internals.texi
+ speedbar.el subr.el tumme.el widget.texi
Marshall T. Vandegrift: changed gnus-fun.el
Martin Neitzel: changed sc.el
Martin Rudalics: changed cus-start.el cus-edit.el files.el wid-edit.el
- window.el flyspell.el font-lock.el mouse.el syntax.c xdisp.c compile.el
- complete.el dired.el frame.c frame.el insdel.c ispell.el keyboard.c
- macmenu.c macterm.c msdos.c and 65 other files
+ window.el find-func.el flyspell.el font-lock.el mouse.el syntax.c
+ xdisp.c compile.el complete.el dired.el frame.c frame.el insdel.c
+ ispell.el keyboard.c macmenu.c macterm.c and 65 other files
Martin Stjernholm: wrote cc-bytecomp.el
and changed cc-engine.el cc-cmds.el cc-langs.el cc-defs.el cc-mode.el
Matt Swift: changed compile.el dired.el editfns.c lisp-mode.el
mm-decode.el outline.el rx.el simple.el startup.el
-Matthew Luckie: changed configure.in
-
Matthew Mundell: changed calendar.texi diary-lib.el files.texi
type-break.el debugging.texi display.texi edebug.texi editfns.c eval.c
fileio.c frames.texi help.texi internals.texi modes.texi nonascii.texi
Michael Albinus: wrote tramp-ftp.el tramp-smb.el
and changed tramp.el tramp.texi tramp-vc.el ange-ftp.el files.el
- tramp-util.el trampver.el files.texi nnml.el tramp-uu.el trampver.texi
- vc.el dired-x.el dired.el faq.texi ffap.el find-dired.el locate.el
- mini.texi rcompile.el socks.el and 4 other files
+ tramp-util.el trampver.el trampver.texi files.texi nnml.el tramp-uu.el
+ vc.el dired-x.el dired.el faq.texi ffap.el fileio.c find-dired.el
+ locate.el mini.texi rcompile.el and 6 other files
-Michael Ben-Gershon: changed acorn.h configure.in riscix1-1.h riscix1-2.h
- unexec.c
+Michael Ben-Gershon: changed acorn.h riscix1-1.h riscix1-2.h unexec.c
Michael Cook: changed gnus-sum.el
and changed comint.el faces.el simple.el editfns.c xfaces.c info.el
xdisp.c minibuf.c wid-edit.el xterm.c subr.el window.el cus-edit.el
diff-mode.el dispextern.h quick-install-emacs xfns.c help.el lisp.h
- textprop.c bytecomp.el and 245 other files
+ textprop.c bytecomp.el and 244 other files
+
+Mirko Vukovic: changed emacs.texi maintaining.texi
Miyashita Hisashi: changed ccl.c coding.c coding.h mule-cmds.el
mule-conf.el mule.el pop3.el
and changed msdos.c config.bat keyboard.c sed1.inp sed2.inp fileio.c
sed3.inp dos-fns.el callproc.c add-log.el alpha.h data.c editfns.c
emacs.c etags.c files.el info.el lread.c mainmake osf1.h tar-mode.el
- and 73 other files
+ and 72 other files
Mosur Mohan: changed etags.c
Nagy Andras: wrote gnus-sieve.el
and changed imap.el gnus.el
-Nakaji Hiroyuki: changed amdx86-64.h configure.in mm-util.el
+Nakagawa Makoto: changed ldap.el
+
+Nakaji Hiroyuki: changed amdx86-64.h mm-util.el
Nakamura Toshikazu: changed w32fns.c
Neil W. Van Dyke: wrote webjump.el
-Nelson H. F. Beebe: changed configure.in
-
Nelson Jose Dos Santos Ferreira: changed nnsoup.el
Nevin Kapur: changed nnmail.el gnus-sum.el nnimap.el gnus-group.el
Niklas Morberg: changed nnweb.el gnus-art.el nnimap.el spam.el
-Nikolaj Schumacher: changed compile.el rx.el
+Nikolaj Schumacher: changed compile.el flymake.el rx.el
Nils Ackermann: changed message.el nnmh.el
Noah Friedman: wrote eldoc.el rlogin.el rsz-mini.el type-break.el
and changed comint.el emacs-buffer.gdb files.el mailabbrev.el sendmail.el
- subr.el timer.el yow.el battery.el complete.el config.in configure.in
- copyright.h fns.c gnu-linux.h hpux7.h irix3-3.h lisp-mnt.el loaddefs.el
- mailalias.el menu-bar.el and 14 other files
+ subr.el timer.el yow.el battery.el complete.el config.in copyright.h
+ fns.c gnu-linux.h hpux7.h irix3-3.h lisp-mnt.el loaddefs.el
+ mailalias.el menu-bar.el pp.el and 13 other files
Nobuyuki Hikichi: changed news-risc.h
and changed imenu.el make-mode.el
Paul Eggert: wrote cal-dst.el rcs2log vcdiff
-and changed editfns.c vc.el Makefile.in configure.in vc-hooks.el data.c
- emacs.c gnus.el calendar.el config.in floatfns.c process.c sysdep.c
- dired.el xterm.c callproc.c fileio.c filelock.c lread.c print.c
- rmail.el and 290 other files
+and changed editfns.c vc.el Makefile.in vc-hooks.el data.c emacs.c
+ gnus.el calendar.el config.in floatfns.c process.c sysdep.c dired.el
+ xterm.c callproc.c fileio.c filelock.c lread.c print.c rmail.el b2m.c
+ and 289 other files
Paul Fisher: changed fns.c
etags.el info.el ses.el tar-mode.el url-http.el which-func.el window.el
Paul Reilly: wrote dgux5-4r3.h gux5-4r2.h
-and changed dgux.h lwlib-Xm.c lwlib.c xlwmenu.c configure.in process.c
- xfns.c Makefile.in dgux5-4R2.h dgux5-4R3.h files.el keyboard.c
- lwlib-Xaw.c lwlib-Xm.h lwlib-int.h lwlib.h widget.c widget.h xlwmenu.h
- xmenu.c xterm.c
+and changed dgux.h lwlib-Xm.c lwlib.c xlwmenu.c process.c xfns.c
+ Makefile.in dgux5-4R2.h dgux5-4R3.h files.el keyboard.c lwlib-Xaw.c
+ lwlib-Xm.h lwlib-int.h lwlib.h widget.c widget.h xlwmenu.h xmenu.c
+ xterm.c
Paul Rubin: changed config.h sun2.h texinfmt.el window.c
Pavel Jan\e,Bm\e(Bk: changed COPYING keyboard.c xterm.c xdisp.c Makefile.in
process.c emacs.c lisp.h menu-bar.el ldap.el make-dist xfns.c buffer.c
coding.c eval.c fileio.c flyspell.el fns.c indent.c callint.c
- cus-start.el and 703 other files
+ cus-start.el and 702 other files
Pavel Kobiakov: changed flymake.el flymake.texi
Peter Liljenberg: wrote elint.el
-Peter O'gorman: changed configure.in frame.h gtkutil.c termhooks.h
+Peter O'gorman: changed frame.h gtkutil.c termhooks.h
Peter Povinec: changed term.el
Peter Whaite: changed data.c
-Petr Salinger: changed configure.in gnu-kfreebsd.h
+Petr Salinger: changed gnu-kfreebsd.h
-Petri Kaurinkoski: changed configure.in iris4d.h irix6-0.h irix6-5.h
- usg5-4.h
+Petri Kaurinkoski: changed iris4d.h irix6-0.h irix6-5.h usg5-4.h
Phil Sung: changed wdired.el
+Philip Jackson: wrote org-irc.el
+
Philippe Schnoebelen: wrote gomoku.el mpuz.el
Philippe Waroquiers: changed etags.el term.c
Pinku Surana: changed sql.el
+Piotr Zielinski: wrote org-mouse.el
+
Pmr-Sav: changed mail-utils.el rmail.el
Primoz Peterlin: changed TUTORIAL.sl
pgg-gpg.el
Reiner Steib: wrote gmm-utils.el
-and changed gnus.texi gnus-art.el message.el gnus-sum.el gnus.el
- gnus-group.el gnus-faq.texi mm-util.el gnus-start.el gnus-util.el
- message.texi mml.el gnus-score.el gnus-agent.el gnus-msg.el spam.el
+and changed gnus.texi gnus-art.el message.el gnus-sum.el gnus-faq.texi
+ gnus.el gnus-group.el message.texi mm-util.el gnus-start.el
+ gnus-util.el mml.el gnus-score.el gnus-agent.el gnus-msg.el spam.el
files.el nnmail.el spam-report.el mail-source.el mm-decode.el
- and 170 other files
+ and 171 other files
Remek Trzaska: changed gnus-ems.el
easymenu.el font-lock.el image-mode.el menu-bar.el paren.el
and changed keyboard.c files.el simple.el xterm.c xdisp.c fileio.c
rmail.el process.c sysdep.c xfns.c buffer.c Makefile.in window.c
- configure.in subr.el startup.el emacs.c editfns.c info.el sendmail.el
- dispnew.c and 1337 other files
+ subr.el startup.el emacs.c editfns.c info.el sendmail.el dispnew.c
+ dired.el and 1335 other files
Richard Mlynarik: wrote cl-indent.el ebuff-menu.el ehelp.el env.c
rfc822.el terminal.el yow.el
Rick Sladkey: wrote backquote.el
and changed gud.el intervals.c intervals.h simple.el
-Rob Browning: changed configure.in
-
Rob Kaut: changed vhdl-mode.el
Rob Riepel: wrote tpu-edt.el tpu-extras.el tpu-mapper.el vt-control.el
Roland Mcgrath: wrote autoload.el etags.el find-dired.el grep.el
map-ynp.el
-and changed compile.el add-log.el configure.in files.el vc.el Makefile.in
- simple.el mailabbrev.el buffer.c comint.el upd-copyr.el etags.c
- menu-bar.el loaddefs.el mem-limits.h ralloc.c fileio.c data.c process.c
- rlogin.el rmail.el and 137 other files
+and changed compile.el add-log.el files.el vc.el Makefile.in simple.el
+ mailabbrev.el buffer.c comint.el upd-copyr.el etags.c menu-bar.el
+ loaddefs.el mem-limits.h ralloc.c fileio.c data.c process.c rlogin.el
+ rmail.el shell.el and 136 other files
Roland Winkler: changed bibtex.el appt.el artist.el conf-mode.el
flyspell.el ispell.el make-mode.el sgml-mode.el sh-script.el
comint.el compile.el message.el puresize.h replace.el subr.el
files.texi gnus-fun.el gnus.texi help-fns.el make-dist rcirc.el
antlr-mode.el bookmark.el buffer.c diary-lib.el dired.el
- and 130 other files
+ and 129 other files
Roman Belenov: changed which-func.el
and changed cl-indent.el font-lock.el ange-ftp.el mouse.el tex-mode.el
vc-cvs.el add-log.el bindings.el bookmark.el debug.el diary-lib.el
dired.el pcvs.el sgml-mode.el simple.el browse-url.el buff-menu.el
- bytecomp.el cc-mode.el compile.el etags.el and 97 other files
+ bytecomp.el cc-mode.el compile.el etags.el and 96 other files
Samuel Tardieu: changed smime.el
Sascha L\e,A|\e(Bdecke: wrote mml1991.el
and changed gnus-win.el
-Sascha Wilde: changed pgg-gpg.el pgg.el pgg.texi configure.in
+Sascha Wilde: changed pgg-gpg.el pgg.el pgg.texi
Satyaki Das: wrote mh-acros.el mh-gnus.el mh-junk.el mh-search.el
mh-speed.el mh-thread.el mh-tool-bar.el
pgg-gpg.el mml2015.el gnus-agent.el mml.el mm-decode.el mml1991.el
gnus-group.el gnus-msg.el pgg-pgp5.el gnus-sieve.el browse-url.el
gnus-int.el gnus.el pgg-parse.el gnus-cache.el mail-source.el
- and 88 other files
+ and 87 other files
Simon Leinen: changed smtpmail.el Makefile Makefile.in cm.c cm.h hpux9.h
indent.c process.c sc.texinfo sgml-mode.el term.c xfns.c xmenu.c
and changed vc.el font-lock.el pcvs.el newcomment.el subr.el lisp.h
keyboard.c fill.el tex-mode.el keymap.c vc-hooks.el compile.el
simple.el files.el alloc.c easy-mmode.el regex.c syntax.c info.el
- xdisp.c sh-script.el and 529 other files
+ xdisp.c sh-script.el and 528 other files
Steinar Bang: changed imap.el
Stephen A. Wood: changed fortran.el
-Stephen Berman: changed allout.el find-dired.el recentf.el
-
-Stephen C. Gilardi: changed configure.in
+Stephen Berman: changed allout.el find-dired.el newcomment.el recentf.el
Stephen Compall: changed saveplace.el texinfo.el
Steve Fisk: wrote cal-tex.el
+Steve Grubb: changed vcdiff
+
Steve Nygard: changed unexnext.c
Steve Strassman: wrote spook.el
Steven Suhr: changed dispnew.c scroll.c term.c termchar.h
-Steven Tamm: changed macterm.c make-package mac.c macfns.c configure.in
- unexmacosx.c INSTALL mac-win.el Makefile.in README darwin.h editfns.c
- lread.c macmenu.c scroll-bar.el MACHINES config.h config.in dispnew.c
- eval.c fileio.c and 7 other files
+Steven Tamm: changed macterm.c make-package mac.c macfns.c unexmacosx.c
+ INSTALL mac-win.el Makefile.in README darwin.h editfns.c lread.c
+ macmenu.c scroll-bar.el MACHINES config.h config.in dispnew.c eval.c
+ fileio.c fns.c and 6 other files
Stewart M. Clamen: wrote cal-mayan.el
Sundar Narasimhan: changed rnews.el rnewspost.el
-Sven Joachim: changed arc-mode.el de-refcard.tex dired-aux.el files.el
- files.texi gnus.texi help.el mule.texi sed3v2.inp sh-script.el
- simple.el vc-bzr.el view.el
+Sven Joachim: changed dired-aux.el files.el arc-mode.el de-refcard.tex
+ files.texi gnus-sum.el gnus.texi help.el mule.texi sed3v2.inp
+ sh-script.el simple.el vc-bzr.el view.el
Svend Tollak Munkejord: changed deuglify.el
and changed ewoc.el info.el processes.texi vc.el zone.el Makefile.in
lisp-mode.el fileio.c scheme.el text.texi TUTORIAL.it bindat.el
dcl-mode.el display.texi files.el gnus.texi pcvs.el startup.el sysdep.c
- vc-rcs.el MORE.STUFF and 134 other files
+ vc-rcs.el MORE.STUFF and 133 other files
Thierry Emery: changed kinsoku.el timezone.el url-http.el wid-edit.el
Tim Fleehart: wrote makefile.nt
-Tim Van Holder: changed emacsclient.c Makefile.in compile.el configure.in
+Tim Van Holder: changed emacsclient.c Makefile.in compile.el
which-func.el
Tobias C. Rittweiler: changed font-lock.el
Ulrich Mueller: changed gud.el ChgPane.c ChgSel.c Makefile.in
XMakeAssoc.c bibtex.el case-table.el files.el fortran.el iso-acc.el
- msdog-xtra.texi simple.el sysdep.c
+ msdog-xtra.texi pop.c simple.el sysdep.c
Ulrich Neumerkel: changed xterm.c
url-http.el url-util.el url.el vc-dav.el
and changed url-handlers.el url-file.el url-methods.el url-vars.el
url-https.el aclocal.m4 mule-sysdp.el url-imap.el url-news.el
- url-nfs.el configure.in image.el mwheel.el url-about.el url-auth.el
- url-cid.el url-dired.el url-expand.el url-ftp.el url-history.el
- url-irc.el and 6 other files
+ url-nfs.el image.el mwheel.el url-about.el url-auth.el url-cid.el
+ url-dired.el url-expand.el url-ftp.el url-history.el url-irc.el
+ url-misc.el and 5 other files
William Smith: changed strftime.c
Wolfgang Jenkner: changed conf-mode.el gnus-sum.el pcvs.el
Wolfgang Rupprecht: wrote float-sup.el floatfns.c sup-mouse.el
-and changed process.c alloc.c callint.c config.h.in config.in
- configure.in crt0.c data.c fns.c lisp-mode.el lisp.h loadup.el lread.c
- net-utils.el nntp.el print.c sort.el sun3.h ymakefile
+and changed process.c alloc.c callint.c config.h.in config.in crt0.c
+ data.c fns.c lisp-mode.el lisp.h loadup.el lread.c net-utils.el nntp.el
+ print.c sort.el sun3.h ymakefile
Wolfgang Scherer: changed vc-cvs.el
Yamamoto Mitsuharu: changed macterm.c macfns.c mac-win.el mac.c macterm.h
macmenu.c macgui.h image.c macselect.c xdisp.c keyboard.c emacs.c
- makefile.MPW config.h INSTALL Makefile.in macos.texi darwin.h
- unexmacosx.c xfaces.c dispnew.c and 80 other files
+ makefile.MPW Makefile.in config.h INSTALL darwin.h macos.texi process.c
+ unexmacosx.c xfaces.c and 82 other files
Yann Dirson: changed imenu.el
Yuri Shtil: changed etags.c
-Yutaka Niibe: changed indent.c xdisp.c configure.in Makefile.in dispnew.c
- sysdep.c config.in dired.el emacs.c fill.el fns.c gmalloc.c gnu-linux.h
- indent.h process.c simple.el term.c window.c
+Yutaka Niibe: changed indent.c xdisp.c Makefile.in dispnew.c sysdep.c
+ config.in dired.el emacs.c fill.el fns.c gmalloc.c gnu-linux.h indent.h
+ process.c simple.el term.c window.c
Zhang Wei: changed xfns.c erc.el x-win.el
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
+2008-08-16 Chong Yidong <cyd@stupidchicken.com>
+
+ * make-dist: Omit info/.arch-inventory.
+
+2008-08-16 Jason Rumney <jasonr@gnu.org>
+
+ * make-dist (tempdir/nt): Link emacsclient.rc.
+
+2008-08-10 Glenn Morris <rgm@gnu.org>
+
+ * configure.in (cpp_undefs): Rename from `undefs', update uses.
+ Use $srcdir rather than $top_srcdir. Set before calling AC_OUTPUT,
+ and explicitly export there. (Bug#507.) (Sync of trunk 2008-07-01).
+
+2008-08-05 Ulrich Mueller <ulm@gentoo.org>
+
+ * configure.in: Add checks for krb5_error.text and
+ krb5_error.e_text struct members.
+
+ * configure: Regenerate.
+
+2008-07-25 Chong Yidong <cyd@stupidchicken.com>
+
+ * configure.in: Check for getrlimit.
+
+ * configure: Regenerate.
+
+2008-05-02 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * configure.in: Check availability of AvailabilityMacros.h
+ if HAVE_CARBON.
+
+ * configure: Regenerate.
+
+2008-04-11 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * configure.in: Remove hpux10.20 from the desupported list.
+
2008-03-26 Chong Yidong <cyd@stupidchicken.com>
* Version 22.2 released.
See the end of the file for license conditions.
-This directory tree holds version 22.2 of GNU Emacs, the extensible,
+This directory tree holds version 22.3 of GNU Emacs, the extensible,
customizable, self-documenting real-time display editor.
The file INSTALL in this directory says how to build and install GNU
esac
case "${opsys}" in
- bsd386 | bsdos2-1 | bsdos2 | bsdos3 | bsdos4 | bsd4-1 | bsd4-2 | bsd4-3 | usg5-0 | usg5-2-2 | usg5-2 | usg5-3 | ultrix4-3 | 386bsd | hpux | hpux8 | hpux9 | hpux9shr | hpux10 | hpux10-20 | aix3-1 | aix3-2-5 | aix3-2 | aix4-1 | nextstep | ux4800 | uxpds | uxpv )
+ bsd386 | bsdos2-1 | bsdos2 | bsdos3 | bsdos4 | bsd4-1 | bsd4-2 | bsd4-3 | usg5-0 | usg5-2-2 | usg5-2 | usg5-3 | ultrix4-3 | 386bsd | hpux | hpux8 | hpux9 | hpux9shr | hpux10 | aix3-1 | aix3-2-5 | aix3-2 | aix4-1 | nextstep | ux4800 | uxpds | uxpv )
echo "The system that you are configuring on: ${canonical} is considered to be obsolete"
echo "and it is planned to be desupported in the next version of Emacs"
echo "Please email emacs-devel@gnu.org as soon as possible if this system is still in use."
#define HAVE_CARBON 1
_ACEOF
+
+for ac_header in AvailabilityMacros.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
## Specify the install directory
carbon_appdir=
if test "${carbon_appdir_x}" != ""; then
+
for ac_func in gethostname getdomainname dup2 \
rename closedir mkdir rmdir sysinfo getrusage get_current_dir_name \
random lrand48 bcopy bcmp logb frexp fmod rint cbrt ftime res_init setsid \
strerror fpathconf select mktime euidaccess getpagesize tzset setlocale \
-utimes setrlimit setpgid getcwd getwd shutdown getaddrinfo \
+utimes getrlimit setrlimit setpgid getcwd getwd shutdown getaddrinfo \
__fpending mblen mbrlen mbsinit strsignal setitimer ualarm index rindex \
sendto recvfrom getsockopt setsockopt getsockname getpeername \
gai_strerror mkstemp getline getdelim mremap memmove fsync sync bzero \
# endif
#endif
+#include <limits.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
isn't worth using anyway. */
alarm (60);
- for (time_t_max = 1; 0 < time_t_max; time_t_max *= 2)
- continue;
- time_t_max--;
- if ((time_t) -1 < 0)
- for (time_t_min = -1; (time_t) (time_t_min * 2) < 0; time_t_min *= 2)
- continue;
+ for (;;)
+ {
+ t = (time_t_max << 1) + 1;
+ if (t <= time_t_max)
+ break;
+ time_t_max = t;
+ }
+ time_t_min = - ((time_t) ~ (time_t) 0 == (time_t) -1) - time_t_max;
+
delta = time_t_max / 997; /* a suitable prime number */
for (i = 0; i < N_STRINGS; i++)
{
&& mktime_test ((time_t) (60 * 60 * 24))))
return 1;
- for (j = 1; 0 < j; j *= 2)
+ for (j = 1; ; j <<= 1)
if (! bigtime_test (j))
return 1;
- if (! bigtime_test (j - 1))
+ else if (INT_MAX / 2 < j)
+ break;
+ if (! bigtime_test (INT_MAX))
return 1;
}
return ! (irix_6_4_bug () && spring_forward_gap () && year_2050_test ());
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <stdio.h>
+#include <sys/types.h> /* for off_t */
+ #include <stdio.h>
int
main ()
{
-return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
+int (*fp) (FILE *, off_t, int) = fseeko;
+ return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
;
return 0;
}
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#define _LARGEFILE_SOURCE 1
-#include <stdio.h>
+#include <sys/types.h> /* for off_t */
+ #include <stdio.h>
int
main ()
{
-return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
+int (*fp) (FILE *, off_t, int) = fseeko;
+ return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
;
return 0;
}
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
+ { echo "$as_me:$LINENO: checking for krb5_error.text" >&5
+echo $ECHO_N "checking for krb5_error.text... $ECHO_C" >&6; }
+if test "${ac_cv_member_krb5_error_text+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <krb5.h>
+
+int
+main ()
+{
+static krb5_error ac_aggr;
+if (ac_aggr.text)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_member_krb5_error_text=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <krb5.h>
+
+int
+main ()
+{
+static krb5_error ac_aggr;
+if (sizeof ac_aggr.text)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_member_krb5_error_text=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_member_krb5_error_text=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_member_krb5_error_text" >&5
+echo "${ECHO_T}$ac_cv_member_krb5_error_text" >&6; }
+if test $ac_cv_member_krb5_error_text = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_ERROR_TEXT 1
+_ACEOF
+
+
+fi
+{ echo "$as_me:$LINENO: checking for krb5_error.e_text" >&5
+echo $ECHO_N "checking for krb5_error.e_text... $ECHO_C" >&6; }
+if test "${ac_cv_member_krb5_error_e_text+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <krb5.h>
+
+int
+main ()
+{
+static krb5_error ac_aggr;
+if (ac_aggr.e_text)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_member_krb5_error_e_text=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <krb5.h>
+
+int
+main ()
+{
+static krb5_error ac_aggr;
+if (sizeof ac_aggr.e_text)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_member_krb5_error_e_text=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_member_krb5_error_e_text=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_member_krb5_error_e_text" >&5
+echo "${ECHO_T}$ac_cv_member_krb5_error_e_text" >&6; }
+if test $ac_cv_member_krb5_error_e_text = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_ERROR_E_TEXT 1
+_ACEOF
+
+
+fi
fi
test "${exec_prefix}" != NONE &&
exec_prefix=`echo "${exec_prefix}" | sed 's,\([^/]\)/*$,\1,'`
+# Now get this: Some word that is part of the ${srcdir} directory name
+# or the ${configuration} value might, just might, happen to be an
+# identifier like `sun4' or `i386' or something, and be predefined by
+# the C preprocessor to some helpful value like 1, or maybe the empty
+# string. Needless to say consequent macro substitutions are less
+# than conducive to the makefile finding the correct directory.
+cpp_undefs="`echo $srcdir $configuration $canonical |
+ sed -e 's/[^a-zA-Z0-9_]/ /g' -e 's/^/ /' -e 's/ *$//' \
+ -e 's/ */ -U/g' -e 's/-U[0-9][^ ]*//g'`"
+
## Check if the C preprocessor will convert `..' to `. .'. If so, set
## CPP_NEED_TRADITIONAL to `yes' so that the code to generate Makefile
## from Makefile.c can correctly provide the arg `-traditional' to the
#
# INIT-COMMANDS
#
-GCC="$GCC" NON_GNU_CPP="$NON_GNU_CPP" CPP="$CPP" CPP_NEED_TRADITIONAL="$CPP_NEED_TRADITIONAL" CPPFLAGS="$CPPFLAGS"
+GCC="$GCC" NON_GNU_CPP="$NON_GNU_CPP" CPP="$CPP" CPP_NEED_TRADITIONAL="$CPP_NEED_TRADITIONAL" CPPFLAGS="$CPPFLAGS" cpp_undefs="$cpp_undefs"
_ACEOF
# and lib-src/Makefile from ${srcdir}/lib-src/Makefile.c
# This must be done after src/config.h is built, since we rely on that file.
-# Now get this: Some word that is part of the ${srcdir} directory name
-# or the ${configuration} value might, just might, happen to be an
-# identifier like `sun4' or `i386' or something, and be predefined by
-# the C preprocessor to some helpful value like 1, or maybe the empty
-# string. Needless to say consequent macro substitutions are less
-# than conducive to the makefile finding the correct directory.
-undefs="`echo $top_srcdir $configuration $canonical |
-sed -e 's/[^a-zA-Z0-9_]/ /g' -e 's/^/ /' -e 's/ *$//' \
- -e 's/ */ -U/g' -e 's/-U[0-9][^ ]*//g' \
-`"
-
echo creating src/epaths.h
${MAKE-make} epaths-force
sed -e '1,/start of cpp stuff/d'\
-e 's,/\*\*/#\(.*\)$,/* \1 */,' \
< Makefile.c > junk.c
- $CPP $undefs -I. -I$srcdir/src $CPPFLAGS junk.c | \
+ $CPP $cpp_undefs -I. -I$srcdir/src $CPPFLAGS junk.c | \
sed -e 's/^ / /' -e '/^#/d' -e '/^[ \f]*$/d' > junk2.c
cat junk1.c junk2.c > Makefile.new
rm -f junk.c junk1.c junk2.c
sed -e '1,/start of cpp stuff/d'\
-e 's,/\*\*/#\(.*\)$,/* \1 */,' \
< Makefile.c > junk.c
- $CPP $undefs -I. -I$srcdir/src $CPPFLAGS junk.c | \
+ $CPP $cpp_undefs -I. -I$srcdir/src $CPPFLAGS junk.c | \
sed -e 's/^ / /' -e '/^#/d' -e '/^[ \f]*$/d' > junk2.c
cat junk1.c junk2.c > Makefile.new
rm -f junk.c junk1.c junk2.c
esac
case "${opsys}" in
- bsd386 | bsdos2-1 | bsdos2 | bsdos3 | bsdos4 | bsd4-1 | bsd4-2 | bsd4-3 | usg5-0 | usg5-2-2 | usg5-2 | usg5-3 | ultrix4-3 | 386bsd | hpux | hpux8 | hpux9 | hpux9shr | hpux10 | hpux10-20 | aix3-1 | aix3-2-5 | aix3-2 | aix4-1 | nextstep | ux4800 | uxpds | uxpv )
+ bsd386 | bsdos2-1 | bsdos2 | bsdos3 | bsdos4 | bsd4-1 | bsd4-2 | bsd4-3 | usg5-0 | usg5-2-2 | usg5-2 | usg5-3 | ultrix4-3 | 386bsd | hpux | hpux8 | hpux9 | hpux9shr | hpux10 | aix3-1 | aix3-2-5 | aix3-2 | aix4-1 | nextstep | ux4800 | uxpds | uxpv )
echo "The system that you are configuring on: ${canonical} is considered to be obsolete"
echo "and it is planned to be desupported in the next version of Emacs"
echo "Please email emacs-devel@gnu.org as soon as possible if this system is still in use."
### Use Mac OS X Carbon API to implement GUI.
if test "${HAVE_CARBON}" = "yes"; then
AC_DEFINE(HAVE_CARBON, 1, [Define to 1 if you are using the Carbon API on Mac OS X.])
+ AC_CHECK_HEADERS(AvailabilityMacros.h)
## Specify the install directory
carbon_appdir=
if test "${carbon_appdir_x}" != ""; then
rename closedir mkdir rmdir sysinfo getrusage get_current_dir_name \
random lrand48 bcopy bcmp logb frexp fmod rint cbrt ftime res_init setsid \
strerror fpathconf select mktime euidaccess getpagesize tzset setlocale \
-utimes setrlimit setpgid getcwd getwd shutdown getaddrinfo \
+utimes getrlimit setrlimit setpgid getcwd getwd shutdown getaddrinfo \
__fpending mblen mbrlen mbsinit strsignal setitimer ualarm index rindex \
sendto recvfrom getsockopt setsockopt getsockname getpeername \
gai_strerror mkstemp getline getdelim mremap memmove fsync sync bzero \
fi
if test "${with_kerberos5+set}" = set; then
- AC_CHECK_HEADERS(krb5.h)
+ AC_CHECK_HEADERS(krb5.h,
+ AC_CHECK_MEMBERS([krb5_error.text, krb5_error.e_text],,,
+ [#include <krb5.h>]))
else
AC_CHECK_HEADERS(des.h,,
[AC_CHECK_HEADERS(kerberosIV/des.h,,
test "${exec_prefix}" != NONE &&
exec_prefix=`echo "${exec_prefix}" | sed 's,\([^/]\)/*$,\1,'`]
+# Now get this: Some word that is part of the ${srcdir} directory name
+# or the ${configuration} value might, just might, happen to be an
+# identifier like `sun4' or `i386' or something, and be predefined by
+# the C preprocessor to some helpful value like 1, or maybe the empty
+# string. Needless to say consequent macro substitutions are less
+# than conducive to the makefile finding the correct directory.
+[cpp_undefs="`echo $srcdir $configuration $canonical |
+ sed -e 's/[^a-zA-Z0-9_]/ /g' -e 's/^/ /' -e 's/ *$//' \
+ -e 's/ */ -U/g' -e 's/-U[0-9][^ ]*//g'`"]
+
## Check if the C preprocessor will convert `..' to `. .'. If so, set
## CPP_NEED_TRADITIONAL to `yes' so that the code to generate Makefile
## from Makefile.c can correctly provide the arg `-traditional' to the
# and lib-src/Makefile from ${srcdir}/lib-src/Makefile.c
# This must be done after src/config.h is built, since we rely on that file.
-# Now get this: Some word that is part of the ${srcdir} directory name
-# or the ${configuration} value might, just might, happen to be an
-# identifier like `sun4' or `i386' or something, and be predefined by
-# the C preprocessor to some helpful value like 1, or maybe the empty
-# string. Needless to say consequent macro substitutions are less
-# than conducive to the makefile finding the correct directory.
-[undefs="`echo $top_srcdir $configuration $canonical |
-sed -e 's/[^a-zA-Z0-9_]/ /g' -e 's/^/ /' -e 's/ *$//' \
- -e 's/ */ -U/g' -e 's/-U[0-9][^ ]*//g' \
-`"]
-
echo creating src/epaths.h
${MAKE-make} epaths-force
sed -e '1,/start of cpp stuff/d'\
-e 's,/\*\*/#\(.*\)$,/* \1 */,' \
< Makefile.c > junk.c
- $CPP $undefs -I. -I$srcdir/src $CPPFLAGS junk.c | \
+ $CPP $cpp_undefs -I. -I$srcdir/src $CPPFLAGS junk.c | \
sed -e 's/^ / /' -e '/^#/d' -e '/^[ \f]*$/d' > junk2.c
cat junk1.c junk2.c > Makefile.new
rm -f junk.c junk1.c junk2.c
sed -e '1,/start of cpp stuff/d'\
-e 's,/\*\*/#\(.*\)$,/* \1 */,' \
< Makefile.c > junk.c
- $CPP $undefs -I. -I$srcdir/src $CPPFLAGS junk.c | \
+ $CPP $cpp_undefs -I. -I$srcdir/src $CPPFLAGS junk.c | \
sed -e 's/^ / /' -e '/^#/d' -e '/^[ \f]*$/d' > junk2.c
cat junk1.c junk2.c > Makefile.new
rm -f junk.c junk1.c junk2.c
# This is how we know whether to re-run configure in certain cases.
touch src/config.stamp
-], [GCC="$GCC" NON_GNU_CPP="$NON_GNU_CPP" CPP="$CPP" CPP_NEED_TRADITIONAL="$CPP_NEED_TRADITIONAL" CPPFLAGS="$CPPFLAGS"])
+], [GCC="$GCC" NON_GNU_CPP="$NON_GNU_CPP" CPP="$CPP" CPP_NEED_TRADITIONAL="$CPP_NEED_TRADITIONAL" CPPFLAGS="$CPPFLAGS" cpp_undefs="$cpp_undefs"])
m4_if(dnl Do not change this comment
arch-tag: 156a4dd5-bddc-4d18-96ac-f37742cf6a5e
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
+2008-05-04 Glenn Morris <rgm@gnu.org>
+
+ * NEWS: Document removal of duplicated "alt-" input methods.
+
2008-03-26 Chong Yidong <cyd@stupidchicken.com>
* Version 22.2 released.
the latest one are detected. You can then remove those shadows manually
or remove them using `make remove-installed-shadows'.
+** The installation directory name is allowed to have spaces and/or tabs.
+
** New `make.bat' for compiling and installing Gnus under MS Windows
Use `make.bat' if you want to install Gnus under MS Windows, the first
`mml-dnd-protocol-alist' and `mml-dnd-attach-options'. *Note MIME:
(message)MIME.
+** `auto-fill-mode' is enabled by default in Message mode. See
+`message-fill-column'. *Note Message Headers: (message)Various Message
+Variables. (New in Gnus 5.10.12 / Emacs 22.3)
+
\f
* Changes in back ends
stuff, like signing and encryption (*note Security: (message)Security.).
** The tool bars have been updated to use GNOME icons in Group, Summary and
-Message mode. You can also customize the tool bars. This is a new
-feature in Gnus 5.10.9. (Only for Emacs, not in XEmacs.)
+Message mode. You can also customize the tool bars: `M-x customize-apropos
+RET -tool-bar$' should get you started. (Only for Emacs, not in XEmacs.)
** The tool bar icons are now (de)activated correctly in the group buffer,
see the variable `gnus-group-update-tool-bar'. Its default value
** cua.el, cua-mode.el: remove old versions.
+\f
+* Changes in Emacs 22.3
+
+** Support for several obsolete platforms will be removed in the next
+major version of Emacs: Apollo, Acorn, Alliant, Amdahl, Altos 3068,
+Bull DPX/2, Bull SPS-7, AT&T UNIX 7300, AT&T 3b, Aviion Berkeley 4.1
+to 4.3, Celerity, Clipper, Convergent S series, Convex, Cydra, DG/UX,
+Dual, Elxsi, ESIX, Fujitsu F301, GEC 63, Gould, Honeywell XPS100,
+i860, IBM ps/2 aix386, Harris CXUX, Harris Night Hawk 1200/3000,
+Harris Power PC, HP 9000 series 200 or 300, HLH Orion, Hitachi
+SR2001/SR2201, IBM PS/2, Integrated Solutions 386, Integrated
+Solutions Optimum V, Iris, Irix < v6, ISC Unix, ISI 68000, Masscomp
+5000, Megatest 68000, Motorola System V/88, ns16000, National
+Semiconductor 32000, osf1 (s/osf*) Paragon i860, PFU A-series, Plexus,
+Pyramid, RTU 3.0, RISCiX SCO 3.2, sh3el, Sinix, Stride, Sun 1-3, Sun
+RoadRunner, Sequent Symmetry, Sony News, SunOS 4, System V rel 0 to 3,
+Tadpole 68k machines, tahoe, Tandem Integrity S2, targon31, Tektronix,
+TI Nu, NCR Tower 32, U-station, Ultrix, UMAX, UniPlus 5.2, Whitechapel
+Computer Works MG1, Wicat, and Xenix.
+
+*** Support for systems without alloca will be removed.
+
+*** Support for Sun windows will be removed.
+
+*** Support for VMS will be removed.
+
+* Incompatible Editing Changes in Emacs 22.3
+
+** The following input methods were removed in Emacs 22.2, but this was
+not advertised: danish-alt-postfix, esperanto-alt-postfix,
+finnish-alt-postfix, german-alt-postfix, icelandic-alt-postfix,
+norwegian-alt-postfix, scandinavian-alt-postfix, spanish-alt-postfix,
+and swedish-alt-postfix. Use the versions without "alt-", which are
+identical.
+
\f
* Installation Changes in Emacs 22.2
Supposedly the newer 32-bit version of this server doesn't have the
problem.
-** Known problems with the MS-Windows port of Emacs 22.1
+** Emacs crashes when opening a file with a UNC path and rails-mode is loaded.
+
+Loading rails-mode seems to interfere with UNC path handling. This has been
+reported as a bug against both Emacs and rails-mode, so look for an updated
+rails-mode that avoids this crash, or avoid using UNC paths if using
+rails-mode.
+
+** Known problems with the MS-Windows port of Emacs 22.3
M-x term does not work on MS-Windows. TTY emulation on Windows is
undocumented, and programs such as stty which are used on posix platforms
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
2008-03-26 Chong Yidong <cyd@stupidchicken.com>
* Version 22.2 released.
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
+2008-08-05 Ulrich Mueller <ulm@gentoo.org>
+
+ * pop.c (socket_connection): Add conditionals for
+ HAVE_KRB5_ERROR_TEXT and HAVE_KRB5_ERROR_E_TEXT to support
+ compilation with MIT Kerberos and Heimdal, respectively.
+
+2008-04-24 Adam Go\e,B3j\e(Bbiowski <adamg@pld-linux.org> (tiny change)
+
+ * Makefile.in (etags${EXEEXT}, ctags${EXEEXT}): Fix quote typo.
+
+2008-04-18 Steve Grubb <sgrubb@redhat.com> (tiny change)
+
+ * vcdiff: Use mktemp (CVE-2008-1694).
+
+2008-04-10 Jason Rumney <jasonr@gnu.org>
+
+ * makefile.w32-in (CLIENTRES): New variable and target.
+ (TRES): Remove.
+ ($(BLD)/emacsclientw.exe): Use $(CLIENTRES) instead of $(TRES).
+
2008-03-26 Chong Yidong <cyd@stupidchicken.com>
* Version 22.2 released.
${CC} -c ${BASE_CFLAGS} -DCONFIG_BROKETS -DINHIBIT_STRING_HEADER ${srcdir}/../src/regex.c
etags${EXEEXT}: ${srcdir}/etags.c $(GETOPTDEPS) $(REGEXPDEPS) ../src/config.h
- $(CC) ${ALL_CFLAGS} -DEMACS_NAME="\"GNU Emacs"\" -DVERSION="\"${version}\"" ${srcdir}/etags.c $(GETOPTOBJS) $(REGEXPOBJ) $(LOADLIBES) -o etags
+ $(CC) ${ALL_CFLAGS} -DEMACS_NAME="\"GNU Emacs\"" -DVERSION="\"${version}\"" ${srcdir}/etags.c $(GETOPTOBJS) $(REGEXPOBJ) $(LOADLIBES) -o etags
ebrowse${EXEEXT}: ${srcdir}/ebrowse.c $(GETOPTDEPS) ../src/config.h
$(CC) ${ALL_CFLAGS} -DVERSION="\"${version}\"" ${srcdir}/ebrowse.c $(GETOPTOBJS) $(LOADLIBES) -o ebrowse
/* We depend on etags to assure that parallel makes don\'t write two
etags.o files on top of each other. */
ctags${EXEEXT}: etags${EXEEXT}
- $(CC) ${ALL_CFLAGS} -DCTAGS -DEMACS_NAME="\"GNU Emacs"\" -DVERSION="\"${version}\"" ${srcdir}/etags.c $(GETOPTOBJS) $(REGEXPOBJ) $(LOADLIBES) -o ctags
+ $(CC) ${ALL_CFLAGS} -DCTAGS -DEMACS_NAME="\"GNU Emacs\"" -DVERSION="\"${version}\"" ${srcdir}/etags.c $(GETOPTOBJS) $(REGEXPOBJ) $(LOADLIBES) -o ctags
profile${EXEEXT}: ${srcdir}/profile.c ../src/config.h
$(CC) ${ALL_CFLAGS} ${srcdir}/profile.c $(LOADLIBES) -o profile
.PHONY: $(ALL)
-VERSION = 22.2
+VERSION = 22.3
LOCAL_FLAGS = -DWINDOWSNT -DDOS_NT -DSTDC_HEADERS=1 -DNO_LDAV=1 \
-DNO_ARCHIVES=1 -DHAVE_CONFIG_H=1 -I../nt/inc \
$(BLD)/getopt.$(O) \
$(BLD)/getopt1.$(O) \
$(BLD)/ntlib.$(O)
-TRES = ../nt/$(BLD)/emacs.res
+CLIENTRES = ../nt/$(BLD)/emacsclient.res
-$(TRES): ../nt/emacs.rc
- $(RC) $(RC_OUT)../nt/$(BLD)/emacs.res $(ALL_DEPS)
+$(CLIENTRES): ../nt/emacsclient.rc
+ @echo Emacsclient resource file must be built from nt directory
+ @exit -1
$(BLD)/emacsclient.exe: $(ECLIENTOBJS)
# put wsock32.lib before $(LIBS) to ensure we don't link to ws2_32.lib
$(LINK) $(LINK_OUT)$@ $(LINK_FLAGS) $(ECLIENTOBJS) $(WSOCK32) $(USER32) $(COMCTL32) $(LIBS)
-$(BLD)/emacsclientw.exe: $(ECLIENTOBJS) $(TRES)
+$(BLD)/emacsclientw.exe: $(ECLIENTOBJS) $(CLIENTRES)
# put wsock32.lib before $(LIBS) to ensure we don't link to ws2_32.lib
- $(LINK) $(LINK_OUT)$@ $(TRES) -mwindows $(LINK_FLAGS) $(ECLIENTOBJS) $(WSOCK32) $(USER32) $(COMCTL32) $(LIBS)
+ $(LINK) $(LINK_OUT)$@ $(CLIENTRES) -mwindows $(LINK_FLAGS) $(ECLIENTOBJS) $(WSOCK32) $(USER32) $(COMCTL32) $(LIBS)
# emacsclient.$(O) depends on makefile.w32-in because makefile.w32-in
# can be edited to define VERSION string, which is part of ECLIENT_CFLAGS.
krb5_free_principal (kcontext, server);
if (rem)
{
+ strcpy (pop_error, KRB_ERROR);
+ strncat (pop_error, error_message (rem),
+ ERROR_MAX - sizeof (KRB_ERROR));
+#if defined HAVE_KRB5_ERROR_TEXT
if (err_ret && err_ret->text.length)
{
- strcpy (pop_error, KRB_ERROR);
- strncat (pop_error, error_message (rem),
- ERROR_MAX - sizeof (KRB_ERROR));
strncat (pop_error, " [server says '",
ERROR_MAX - strlen (pop_error) - 1);
strncat (pop_error, err_ret->text.data,
strncat (pop_error, "']",
ERROR_MAX - strlen (pop_error) - 1);
}
- else
+#elif defined HAVE_KRB5_ERROR_E_TEXT
+ if (err_ret && err_ret->e_text && strlen(*err_ret->e_text))
{
- strcpy (pop_error, KRB_ERROR);
- strncat (pop_error, error_message (rem),
- ERROR_MAX - sizeof (KRB_ERROR));
+ strncat (pop_error, " [server says '",
+ ERROR_MAX - strlen (pop_error) - 1);
+ strncat (pop_error, *err_ret->e_text,
+ ERROR_MAX - strlen (pop_error) - 1);
+ strncat (pop_error, "']",
+ ERROR_MAX - strlen (pop_error) - 1);
}
+#endif
if (err_ret)
krb5_free_error (kcontext, err_ret);
krb5_auth_con_free (kcontext, auth_context);
case $f in
s.* | */s.*)
if
- rev1=/tmp/geta$$
+ rev1=`mktemp /tmp/geta.XXXXXXXX`
get -s -p -k $sid1 "$f" > $rev1 &&
case $sid2 in
'')
workfile=`expr " /$f" : '.*/s.\(.*\)'`
;;
*)
- rev2=/tmp/getb$$
+ rev2=`mktemp /tmp/getb.XXXXXXXX`
get -s -p -k $sid2 "$f" > $rev2
workfile=$rev2
esac
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
+2008-09-03 Alan Mackenzie <acm@muc.de>
+
+ * progmodes/cc-defs.el (c-version): Increment to 5.31.6.
+
+2008-09-03 Masatake YAMATO <jet@gyve.org>
+
+ * progmodes/cc-fonts.el (gtkdoc-font-lock-doc-comments): Highlight
+ name of parameters in document body. (sync from trunk 2007-08-23)
+
+2008-08-30 Glenn Morris <rgm@gnu.org>
+
+ * subr.el (make-variable-frame-local): Tweak obsolescence message.
+
+2008-08-29 Chong Yidong <cyd@stupidchicken.com>
+
+ * image-mode.el (image-mode): Fix 2008-07-19 change.
+
+2008-08-26 Juanma Barranquero <lekktu@gmail.com>
+
+ * facemenu.el (facemenu-unlisted-faces): Fix obsolescence declaration.
+
+ * hi-lock.el (hi-lock-mode): Fix typo in docstring.
+
+ * icomplete.el (icomplete-compute-delay, icomplete-get-keys): Doc fixes.
+ (icomplete-delay-completions-threshold): Fix typo in docstring.
+
+ * speedbar.el (speedbar-stealthy-function-list)
+ (speedbar-verbosity-level, speedbar-supported-extension-expressions)
+ (speedbar-update-current-file, speedbar-add-indicator)
+ (speedbar-tag-expand): Reflow docstrings.
+ (speedbar-use-imenu-flag, speedbar-use-tool-tips-flag)
+ (speedbar-ignored-directory-regexp, speedbar-file-unshown-regexp)
+ (speedbar-file-regexp, speedbar-message, speedbar-item-info)
+ (speedbar-files-item-info, speedbar-fetch-replacement-function)
+ (speedbar-maybe-add-localized-support)
+ (speedbar-generic-list-positioned-group-p, speedbar-insert-generic-list)
+ (speedbar-extract-one-symbol, speedbar-recenter-to-top)
+ (speedbar-recenter, speedbar-separator-face): Fix typos in docstrings.
+ (speedbar-ignored-directory-expressions, speedbar-handle-delete-frame)
+ (speedbar-show-info-under-mouse, speedbar-directory-buttons)
+ (speedbar-check-vc-this-line, speedbar-files-line-directory)
+ (speedbar-buffer-buttons, speedbar-buffer-buttons-temp)
+ (speedbar-buffers-line-directory): Doc fixes.
+
+ * tool-bar.el (tool-bar-add-item): Fix typo in docstring.
+
+ * emacs-lisp/edebug.el (edebug-unwrap*, edebug-signal)
+ (edebug-restore-status): Doc fixes.
+ (edebug-gensym, edebug-top-level-nonstop, edebug-eval-display)
+ (edebug-eval-result-list, edebug-eval-redisplay, edebug)
+ (edebug-trace): Fix typos in docstrings.
+
+ * emulation/tpu-edt.el (tpu-match-beginning, tpu-match-end)
+ (tpu-check-match, tpu-goto-breadcrumb, tpu-reset-screen-size)
+ (tpu-toggle-overwrite-mode, tpu-include, tpu-get, tpu-what-line)
+ (tpu-insert-escape, tpu-insert-formfeed, tpu-end-define-macro-key)
+ (tpu-check-search-case, tpu-select, tpu-unselect, tpu-trim-line-ends)
+ (tpu-toggle-control-keys): Fix typos in docstrings.
+ (tpu-kill-buffer): Doc fix.
+ (tpu-make-file-buffer-list, tpu-toggle-regexp, tpu-cut)
+ (tpu-append-region, tpu-delete-current-char, tpu-emacs-replace):
+ Reflow docstrings.
+
+ * eshell/em-smart.el (eshell-review-quick-commands): Doc fix.
+
+ * eshell/esh-arg.el (eshell-quote-backslash): Fix typo in docstring.
+
+ * play/solitaire.el (solitaire, solitaire-mode-map, solitaire-mode-hook)
+ (solitaire-mode, solitaire, solitaire-solve): Fix typos in docstrings.
+
+ * progmodes/gdb-ui.el (gdb-source-info): Fix typo in docstring.
+
+ * progmodes/python.el (python-comment-line-p, python-blank-line-p)
+ (python-skip-out): Doc fixes.
+
+2008-08-25 Jay Belanger <jay.p.belanger@gmail.com>
+
+ * calc/calc-units.el (math-simplify-units-quotient): Replace
+ missing exponent.
+
+2008-08-24 Romain Francoise <romain@orebokech.com>
+
+ * progmodes/python.el (run-python): Remove '' from sys.path.
+
+2008-08-23 Glenn Morris <rgm@gnu.org>
+
+ * dired-x.el (dired-guess-shell-alist-user): Doc fix.
+
+2008-08-23 Chong Yidong <cyd@stupidchicken.com>
+
+ * subr.el (temp-buffer-show-hook): Doc fix.
+
+2008-08-18 Chong Yidong <cyd@stupidchicken.com>
+
+ * emulation/edt.el (edt-default-emulation-setup): Share
+ global-buffers-menu-map with the emulated global map.
+
+2008-08-16 Chong Yidong <cyd@stupidchicken.com>
+
+ * textmodes/flyspell.el (flyspell-word): Revert last change.
+
+2008-08-15 Glenn Morris <rgm@gnu.org>
+
+ * eshell/em-ls.el (eshell-ls-files): List one per line in a pipeline.
+ (Bug#699)
+
+2008-08-13 Martin Rudalics <rudalics@gmx.at>
+
+ * emacs-lisp/find-func.el (find-library): Wrap search for
+ library name in condition-case to avoid reporting a scan-error.
+ (Bug#563) (sync from trunk 2008-01-25)
+
+2008-08-12 Juanma Barranquero <lekktu@gmail.com>
+
+ * desktop.el (desktop-minor-mode-table): Add `savehist-mode'.
+
+ * play/solitaire.el (solitaire-solve): Err out if the solitaire
+ is already in progress.
+
+2008-08-12 NAKAGAWA Makoto <gha03025@nifty.ne.jp> (tiny change)
+
+ * net/ldap.el (ldap-search-internal): Tweak URL regexp.
+
+2008-08-10 Glenn Morris <rgm@gnu.org>
+
+ * Makefile.in (bootstrap-prepare): Explictly pass EMACS to sub-makes
+ that use it, for non-GNU makes (sync from trunk 2008-06-08).
+
+ * cus-dep.el (generated-custom-dependencies-file): Doc fix (sync from
+ trunk 2008-06-05).
+
+ * finder.el (generated-finder-keywords-file, finder-exit):
+ Doc fix (sync from trunk 2008-06-05).
+
+ * simple.el (toggle-truncate-lines): Doc fix (sync from trunk
+ 2008-04-10).
+
+ * subr.el (locate-library): Doc fix (sync from trunk 2008-06-10).
+
+ * emacs-lisp/bytecomp.el (byte-compile-maybe-guarded): Doc fix (sync
+ from trunk 2008-06-13).
+ (byte-compile-file): Doc fix (sync from trunk 2008-04-27).
+
+ * progmodes/f90.el (f90-beginning-of-subprogram)
+ (f90-end-of-subprogram): Only give a message when interactive (sync
+ from trunk 2008-06-12).
+
+ * progmodes/fortran.el (fortran-end-of-subprogram): Check for a match
+ before trying to move there (sync from trunk 2008-06-11).
+
+ * calendar/cal-bahai.el (holiday-bahai): Use an algorithm actually
+ relevant to this calendar system (sync from trunk 2008-03-31).
+ (calendar-bahai-date-string): Avoid an error for pre-Bahai dates (sync
+ from trunk 2008-03-31).
+ (calendar-print-bahai-date): Handle pre-Bahai dates (sync from trunk
+ 2008-03-20).
+ (calendar-absolute-from-bahai): Fix the leap-year case (sync from trunk
+ 2008-03-20).
+
+ * calendar/calendar.el (increment-calendar-month): Optionally handle
+ systems without 12 months per year (sync from trunk 2008-03-31; needed
+ for above holiday-bahai fix).
+
+ * calendar/cal-islam.el (holiday-islamic): Doc fix (sync from trunk
+ 2008-04-23).
+
+ * calendar/cal-julian.el (holiday-julian): Fix a problem with holidays
+ in the last fortnight in Julian October (sync from trunk 2008-03-31).
+
+ * calendar/cal-tex.el (cal-tex-preamble-extra): Fix custom type (sync
+ from trunk 2008-04-11).
+
+ * calendar/calendar.el (calendar-nth-named-absday)
+ (calendar-nth-named-day):
+ * calendar/diary-lib.el (list-sexp-diary-entries, diary-float):
+ * calendar/holidays.el (holiday-float):
+ Doc fixes (sync from trunk 2008-04-29).
+
+ * calendar/diary-lib.el (simple-diary-display, diary-show-all-entries)
+ (make-diary-entry): Respect non-nil values of pop-up-frames (sync from
+ trunk 2008-03-28).
+
+ * calendar/diary-lib.el (diary-remind): Doc fix.
+
+2008-08-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * kmacro.el (kmacro-exec-ring-item): Add autoload.
+
+ * files.el (auto-save-visited-file-name): Move definition to
+ fileio.c.
+
+ * cus-start.el (all): Handle auto-save-visited-file-name.
+
+2008-08-02 Chong Yidong <cyd@stupidchicken.com>
+
+ * cus-edit.el (custom-save-all): Avoid destroying symlink if
+ already visiting the custom file.
+
+ * pgg-gpg.el (pgg-gpg-process-region): Accept any remaining
+ pending output coming after the status change.
+
+2008-07-31 Sven Joachim <svenjoac@gmx.de>
+
+ * files.el (abbreviate-file-name): When replacing $HOME with ~,
+ turn off case-fold-search.
+
+2008-07-31 Joachim Nilsson <joachim.nilsson@member.fsf.org> (tiny change)
+
+ * progmodes/cc-styles.el (c-style-alist): For the Ellemtel style,
+ move the (arglist-cont-nonempty) from c-offsets-alist to
+ c-hanging-braces-alist like other styles already have.
+
+2008-07-19 Markus Triska <markus.triska@gmx.at>
+
+ * image-mode.el (image-mode): Set image-mode-text-map when image
+ cannot be displayed.
+
+2008-07-28 Chong Yidong <cyd@stupidchicken.com>
+
+ * textmodes/flyspell.el (flyspell-word, flyspell-large-region)
+ (flyspell-region): Call ispell-maybe-find-aspell-dictionaries.
+
+ * simple.el (next-error): Do a redisplay to prevent incorrect
+ recentering (workaround for bug#197).
+
+2008-07-27 Michael Albinus <michael.albinus@gmx.de>
+
+ * net/tramp.el (tramp-perl-directory-files-and-attributes)
+ (tramp-get-device): Make device number a cons cell.
+
+2008-07-25 Chong Yidong <cyd@stupidchicken.com>
+
+ * textmodes/tex-mode.el (tex-compilation-parse-errors): Check for
+ invalid filename strings when parsing tex errors (bug#376).
+
+2008-07-24 Sven Joachim <svenjoac@gmx.de>
+
+ * dired-aux.el (dired-copy-file-recursive): Avoid calling
+ set-file-modes when creating target directories.
+
+2008-07-24 Chong Yidong <cyd@stupidchicken.com>
+
+ * textmodes/enriched.el (enriched-mode-map): Bind C-a and C-j via
+ key remapping, not directly.
+
+2008-07-23 Nikolaj Schumacher <n_schumacher@web.de> (tiny change)
+
+ * progmodes/flymake.el (flymake-errline, flymake-warnline): Use
+ more suitable colors on dark displays.
+
+2008-07-23 Chong Yidong <cyd@stupidchicken.com>
+
+ * shell.el (shell-dynamic-complete-functions): Use
+ comint-dynamic-complete-filename as well (bug#361).
+
+2008-06-21 Alan Mackenzie <acm@muc.de>
+
+ * progmodes/cc-engine.el (c-guess-basic-syntax CASE 5D.5): Fix an
+ infinite loop on invalid syntax.
+
+2008-06-11 Michael Albinus <michael.albinus@gmx.de>
+
+ * net/tramp.el (tramp-make-temp-file): Backport from Tramp 2.1.
+
+2008-06-08 Michael Albinus <michael.albinus@gmx.de>
+
+ * uniquify.el (uniquify-get-proposed-name): Handle remote files.
+
+2008-05-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * tar-mode.el (tar-header-block-summarize): Ensure one space around
+ user&group.
+
+2008-05-25 Ed Reingold <reingold@emr.cs.iit.edu>
+
+ * calendar/cal-hebrew.el (diary-hebrew-yahrzeit):
+ Use diary-ordinal-suffix.
+
+2008-05-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * tar-mode.el (tar-summarize-buffer): Handle GNU Tar @LongLink format.
+
+2008-05-24 Alan Mackenzie <acm@muc.de>
+
+ * progmodes/cc-mode.el (c-postprocess-file-styles): Throw an error
+ if c-file-style is set to a non-string
+
+ (c-neutralize-CPP-line): Surround by `save-excursion'.
+ (c-neutralize-syntax-in-CPP): Optimize for speed.
+
+2008-05-18 David Hull <david@snap.com> (tiny change)
+
+ * vc-hg.el (vc-hg-annotate-re): Recognize the output of --follow.
+
+2008-05-18 mohrmarc <debian@miller-mohr.de> (tiny change)
+
+ * progmodes/fortran.el (fortran-font-lock-keywords-2): Add keywords for
+ logic operators .eqv. and .neqv.
+
+2008-05-17 David Hull <david@snap.com> (tiny change)
+
+ * vc-hg.el (vc-hg-annotate-command): Allow white space before
+ version number.
+
+2008-05-12 Simon Marshall <simon@gnu.org>
+
+ * obsolete/fast-lock.el (fast-lock-cache-directories): Remove "."
+ from its default value and give it the risky-local-variable
+ property (CVE-2008-2142).
+
+2008-05-10 Reiner Steib <reiner.steib@gmx.de>
+
+ * smerge-mode.el (smerge-command-prefix): Fix custom type.
+
+2008-05-05 Carsten Dominik <dominik@science.uva.nl>
+
+ * textmodes/org.el (org-read-date-get-relative): Interpret lone
+ weekday abbreviation as relative to today.
+
+2008-05-01 Nick Roberts <nickrob@snap.net.nz>
+
+ * progmodes/gdb-ui.el (gdb-info-breakpoints-custom):
+ Don't throw error if no file is found.
+
+2008-04-28 Michael Albinus <michael.albinus@gmx.de>
+
+ * net/tramp.el (tramp-replace-environment-variables): Remove it.
+ There is a more simple solution.
+ (tramp-file-name-handler): Apply `substitute-in-file-name' w/o
+ Tramp file name handlers.
+
+2008-04-28 Nick Roberts <nickrob@snap.net.nz>
+
+ * progmodes/gdb-ui.el (gdb-info-breakpoints-custom): Make breakpoint
+ icons work for assembler, i.e. FILE.s, FILE.S (not disassembly).
+ (gdb-goto-breakpoint): Likewise for visiting breakpoints.
+ (gdb-assembler-custom): Be careful not to match other addresses.
+
+2008-04-27 Michael Albinus <michael.albinus@gmx.de>
+
+ * net/tramp.el (tramp-replace-environment-variables): New defun.
+ (tramp-file-name-handler): Use it.
+
+2008-04-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * diff-mode.el (diff-hunk-header-re-unified): Allow elided line counts.
+ (diff-end-of-hunk, diff-unified->context, diff-fixup-modifs)
+ (diff-sanity-check-hunk): Adjust code accordingly.
+
+2008-04-23 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * term/mac-win.el (mac-ts-active-input-buf): Move defvar to macterm.c.
+
+2008-04-12 Nick Roberts <nickrob@snap.net.nz>
+
+ * progmodes/gdb-ui.el (gdb-init-buffer): New function.
+ (gdb-set-gud-minor-mode-existing-buffers)
+ (gdb-info-breakpoints-custom, gdb-get-location)
+ (gdb-set-gud-minor-mode-existing-buffers-1): Use it.
+ Previously gdb-create-define-alist wasn't always run and added to
+ after-save-hook.
+
+ * progmodes/gud.el (gud-tooltip-tips): Use tooltip-event-buffer
+
+2008-04-12 Kevin Ryde <user42@zip.com.au>
+
+ * progmodes/make-mode.el (makefile-fill-paragraph): Treat indented
+ comments like unindented ones.
+
+2008-04-12 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * term/mac-win.el (mac-ae-open-documents): Adjust selection range
+ parameter origins.
+
+2008-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * progmodes/python.el (python-mode): Don't mess with hippie-expand.
+
+2008-04-11 Chong Yidong <cyd@stupidchicken.com>
+
+ * woman.el (woman2-TH): Use string-equal instead of string-match.
+
+2008-04-11 Kevin Ryde <user42@zip.com.au>
+
+ * emacs-lisp/autoload.el (autoload-generate-file-autoloads):
+ Bind print-level to ensure output forms aren't truncated if
+ print-level is set to eval-expression-print-level when going via
+ eval-defun and friends, or has been otherwise fiddled with.
+
+2008-04-09 Michael Albinus <michael.albinus@gmx.de>
+
+ * net/tramp.el (tramp-find-file-name-coding-system-alist):
+ New defun.
+ (tramp-handle-insert-file-contents, tramp-handle-write-region):
+ Use it.
+
+ * net/trampver.el: Update release number.
+
+2008-04-09 Alan Mackenzie <acm@muc.de>
+
+ * font-lock.el (font-lock-extend-after-change-region-function):
+ Make it buffer local.
+
+2008-04-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * progmodes/cc-mode.el (c-basic-common-init): Don't set
+ font-lock-extend-after-change-region-function globally.
+
+2008-04-08 Carsten Dominik <dominik@science.uva.nl>
+
+ * textmodes/org-export-latex.el: New file.
+
+ * textmodes/org-irc.el: New file.
+
+ * textmodes/org-mac-message.el: New file.
+
+ * textmodes/org-publish.el: New file.
+
+ * textmodes/org.el (org-agenda-collect-markers)
+ (org-create-marker-find-array)
+ (org-check-agenda-marker-table, org-extract-log-state-settings)
+ (org-nofm-to-completion, org-refile-goto-last-stored)
+ (org-export-html-convert-special-strings, org-first-list-item-p)
+ (org-imenu-new-marker, org-imenu-get-tree)
+ (org-speedbar-set-agenda-restriction)
+ (org-agenda-set-restriction-lock)
+ (org-agenda-remove-restriction-lock)
+ (org-agenda-maybe-redo, org-compute-latex-and-specials-regexp)
+ (org-do-latex-and-special-faces, org-read-date-display)
+ (org-select-remember-template, org-agenda-copy-local-variable)
+ (org-read-date-get-relative, org-columns-cleanup-item)
+ (org-find-entry-with-id)
+ (org-insert-columns-dblock, org-listtable-to-string)
+ (org-dblock-write:columnview, org-columns-capture-view)
+ (org-edit-headline, org-parse-local-options)
+ (org-in-clocktable-p, org-property-or-variable-value)
+ (org-get-tags-string, org-up-heading-safe)
+ (org-fast-todo-selection, org-get-wdays)
+ (org-switch-to-buffer-other-window, org-agenda-deadline-face)
+ (org-add-link-type, org-columns-content, org-columns-widen)
+ (org-columns-next-allowed-value, org-columns-edit-allowed)
+ (org-columns-store-format)
+ (org-columns-uncompile-format, org-columns-redo)
+ (org-columns-edit-attributes, org-delete-property)
+ (org-set-property, org-columns-update, org-columns-compute)
+ (org-columns-eval)
+ (org-columns-not-in-agenda, org-columns-compute-all)
+ (org-property-next-allowed-value)
+ (org-columns-compile-format, org-fill-paragraph-experimental)
+ (org-string-to-number, org-property-action, org-columns-move-left)
+ (org-columns-new)
+ (org-column-number-to-string, org-property-previous-allowed-value)
+ (org-at-property-p, org-columns-delete)
+ (org-columns-previous-allowed-value)
+ (org-columns-move-right, org-columns-narrow)
+ (org-property-get-allowed-values)
+ (org-verify-version, org-column-string-to-number)
+ (org-delete-property-globally)
+ (org-get-property-block, org-entry-properties, org-entry-get)
+ (org-entry-delete, org-entry-get-with-inheritance)
+ (org-entry-put, org-buffer-property-keys, org-new-column-overlay)
+ (org-overlay-columns)
+ (org-overlay-columns-title, org-remove-column-overlays)
+ (org-column-show-value, org-column-quit, org-column-edit)
+ (org-cached-entry-get, org-table-put-field-property)
+ (org-get-columns-autowidth-alist, turn-on-orgstruct)
+ (orgstruct-error, orgstruct-setup)
+ (orgstruct-make-binding, org-context-p, org-get-local-variables)
+ (org-run-like-in-org-mode)
+ (org-make-link-regexps, org-remove-keyword-keys)
+ (org-get-todo-face, org-export-get-title-from-subtree)
+ (org-assign-fast-keys, org-get-min-level)
+ (org-get-wdays, org-clock-find-position)
+ (org-clock-goto, org-fontify-priorities)
+ (org-get-date-from-calendar)
+ (org-entry-add-to-multivalued-property)
+ (org-entry-remove-from-multivalued-property)
+ (org-entry-member-in-multivalued-property)
+ (org-entry-is-todo-p, org-entry-is-done-p, org-get-todo-state)
+ (org-agenda-get-restriction-and-command)
+ (org-open-link-from-string, org-columns-open-link)
+ (org-go-to-remember-target, org-remember-insinuate)
+ (org-icalendar-cleanup-string, org-first-sibling-p)
+ (org-back-over-empty-lines, org-skip-whitespace)
+ (org-goto-local-auto-isearch)
+ (org-clocktable-steps, org-refile-get-location)
+ (org-kill-line, org-remove-timestamp-with-keyword)
+ (org-local-logging): New functions.
+ (org-agenda-marker-table, org-log-note-how)
+ (org-goto-local-auto-isearch-map)
+ (org-last-remember-storage-locations)
+ (org-imenu-markers, org-agenda-restriction-lock-overlay)
+ (org-speedbar-restriction-lock-overlay)
+ (org-massive-special-regexp)
+ (org-verbatim-re, org-read-date-display-live)
+ (org-agenda-file-regexp, org-complex-heading-regexp)
+ (org-completion-fallback-command, org-todo-log-states)
+ (org-goto-exit-command, org-goto-selected-point)
+ (org-todo-key-alist, org-todo-key-trigger, org-agenda-remove-date)
+ (org-agenda-after-show-hook, org-agenda-skip-unavailable-files)
+ (org-fast-tag-selection-can-set-todo-state, org-local-properties)
+ (org-store-link-functions, org-columns-top-level-marker)
+ (orgstruct-mode-map, org-entry-property-inherited-from)
+ (org-column-overlays, org-current-columns-fmt)
+ (org-current-columns-maxwidths, org-column-map)
+ (org-cached-props): New variables.
+ (org-special-ctrl-k, org-goto-auto-isearch)
+ (org-agenda-todo-keyword-format)
+ (org-remember-use-refile-when-interactive)
+ (org-imenu-depth, org-highlight-latex-fragments-and-specials)
+ (org-agenda-skip-scheduled-if-done, org-extend-today-until)
+ (org-agenda-window-frame-fractions, org-fontify-priorities)
+ (org-agenda-deadline-leaders, org-use-property-inheritance)
+ (org-clock-into-drawer, org-agenda-compact-blocks)
+ (org-use-fast-todo-selection, org-fast-tag-selection-include-todo)
+ (org-edit-timestamp-down-means-later, org-todo-keyword-faces)
+ (org-agenda-deadline-faces, org-remember-store-without-prompt)
+ (org-default-columns-format)
+ (org-agenda-default-appointment-duration)
+ (org-export-with-footnotes, org-clock-out-when-done)
+ (org-global-properties, org-todo-keyword-faces)
+ (org-archive-save-context-info)
+ (org-edit-timestamp-down-means-later)
+ (org-scheduled-past-days, org-export-with-drawers)
+ (org-read-date-prefer-future, org-hide-emphasis-markers)
+ (org-clock-heading-function, org-clock-in-switch-to-state)
+ (org-export-with-special-strings): New options.
+ (org-link-store, org-link-follow, org-latex)
+ (org-remember-templates, org-time-stamp-rounding-minutes)
+ (org-back-over-empty-lines, org-find-base-buffer-visiting)
+ (org-columns-new): Fix typos in docstrings.
+ (org-ctrl-c-star): Implement a missing branch in the decision tree.
+ (org-select-remember-template): Clean the code.
+ (org-prepare-dblock): Add the extra :content parameter.
+ (org-write-agenda): New output type ".ics" files.
+ (org-write-agenda): Call `org-icalendar-verify-function', both for
+ time stamps and for TODO entries.
+ (org-export-as-html): Revert the change that killed the html
+ buffer. Side effects first need to be studied carefully.
+ (org-get-tags-at): Fix the structure of the condition-case statement.
+ (org-ts-regexp0, org-repeat-re, org-display-custom-time)
+ (org-timestamp-change): Fix regulear expressions to swallow the
+ extra character for repeat-shift control.
+ (org-auto-repeat-maybe): Implement the new repeater mechanisms.
+ (org-get-legal-level): Alias to `org-get-valid-level'.
+ (org-dblock-write:clocktable): Add a :link parameter, linking
+ headlines to their location in the Org agenda files.
+ (org-get-tags-at): Bugfix: prevent `org-back-to-heading' from
+ throwing an error when getting tags before headlines.
+ (org-timestamp-change, org-modify-ts-extra)
+ (org-ts-regexp1): Fix timestamp editing.
+ (org-agenda-custom-commands-local-options): New constant.
+ (org-agenda-custom-commands):
+ Use `org-agenda-custom-commands-local-options' to improve customize
+ type. "htmlize": Removed hack to fix face problem with htmlize,
+ it no longer seem necessary.
+ (org-follow-link-hook): New hook.
+ (org-agenda-custom-commands): Add "Component" as a tag for each
+ item in a command serie.
+ (org-open-at-point): Run `org-follow-link-hook'.
+ (org-agenda-schedule): Bugfix: don't display marker type when it
+ is nil.
+ (org-store-link): org-irc required.
+ (org-set-regexps-and-options): Parse the new logging options.
+ (org-todo): Handle the new ways of recording state change stuff.
+ (org-columns-open-link): Fix bug with opening link in column view.
+ (org-todo): Make sure that LOGGING properties are honoured.
+ (org-todo-keywords): Improve docstring.
+ (org-startup-options): Cleanup startup options.
+ (org-set-regexps-and-options): Process the "!" markers.
+ (org-todo): Respect the new logging stuff.
+ (org-add-log-maybe): New parameter HOW that defines how logging
+ should be done and also overrides PURPOSE. Add a docstring.
+ (org-add-log-note): Check if we really need to ask for a note.
+ (org-get-current-options): Digest the new keyword.
+ (org-agenda-reset-markers): Rename from
+ `org-agenda-maybe-reset-markers'. Remove FORCE argument.
+ (org-diary, org-agenda-quit, org-prepare-agenda): Call the renamed
+ function, without force argument.
+ (org-buffer-property-keys): Bind local variables s and p.
+ (org-make-tags-matcher): Allow "" to match an empty or
+ non-existent property value.
+ (org-export-as-html): Join unsorted lists when they directly
+ follow each other. Such lists may be created by headlines that
+ are converted to lists.
+ (org-export-as-html): Use :html-extension instead of
+ org-export-html-extension.
+ (org-store-link): Support for links from `rmail-summary-mode'.
+ (org-columns-new, org-complete, org-set-property): Set the
+ `include-columns' argument in the call to `org-buffer-property-keys'.
+ (org-buffer-property-keys): New argument `include-columns', to
+ include properties expected by any of the COLUMS formats in the
+ current buffer.
+ (org-cleaned-string-for-export): Get rid of drawers first, so that
+ they will be removed also in the text before the first headline.
+ (org-clock-report): Show the clocktable when found.
+ (org-refile): Fix positioning bug when `org-reverse-note-order' is nil.
+ (org-version): With prefix argument, insert `org-version' at point.
+ (org-agenda-goto): Recenter the window after finding the target
+ location, to make sure the correct position will be displayed.
+ (org-agenda-get-deadlines): Don't scale priority with the warning
+ period.
+ (org-insert-heading): Don't break line in the middle of the line.
+ (org-agenda-get-deadlines): Allow `org-deadline-warning-days' to
+ be 0.
+ (org-update-checkbox-count): Revamp to deal with hierarchical
+ beckboxes. This was a patch from Miguel A. Figueroa-Villanueva.
+ (org-schedule, org-deadline): Use `org-remove-timestamp-with-keyword'
+ to make sure all such time stamps are removed.
+ (org-mode): Support for `align'.
+ (org-agenda-get-deadlines): Make sure priorities increase as the
+ due date approaches and is passed.
+ (org-remember-apply-template): Fix problem with tags that contain
+ "_" or "@".
+ (org-make-link-regexps): Improve the regular expression for plain
+ links.
+ (org-agenda-get-closed): List each clocking entry.
+ (org-set-tags): Only tabify before tags if indent-tabs-mode is t.
+ (org-archive-all-done): Fix incorrect number of stars in regexp.
+ (org-global-tags-completion-table): Add the value of org-tag-alist
+ in each buffer, to make sure that also unused tags will be
+ available for completion.
+ (org-columns-edit-value)
+ (org-columns-next-allowed-value): Only update if not in agenda.
+ (org-dblock-write:clocktable): Call `org-clocktable-steps'.
+ (org-archive-subtree): Add the outline tree context as a property.
+ (org-closest-date): New optional argument `prefer'.
+ (org-goto-map, org-get-location): Implement auto-isearch.
+ (org-goto-local-search-forward-headings)
+ (org-get-entries-from-diary): Require diary-lib.
+ (org-agenda-sunrise-sunset): Require solar.
+ (org-export-html-style): Doc fix.
+ (org-get-legal-level): New obsolete alias.
+ (org-get-valid-level): Rename from `org-get-legal-level'.
+ (org-promote, org-demote, org-archive-subtree)
+ (org-remember-handler, org-refile, org-put-clock-overlay): Use it.
+ (org-info): Use info rather than Info-goto-node.
+ (org-entry-properties): Let-bind `clocksum'.
+ (org-unmodified, org-cycle-emulate-tab)
+ (org-descriptive-links, org-link-file-path-type)
+ (org-remember-use-refile-when-interactive)
+ (org-agenda-skip-timestamp-if-done, org-agenda-scheduled-leaders)
+ (org-export-ascii-bullets, org-agenda-deadline-faces)
+ (turn-on-orgstruct++, orgtbl-to-texinfo, org-mhe-get-header)
+ (org-batch-agenda, org-batch-agenda-csv, org-fix-agenda-info)
+ (org-kill-note-or-show-branches): Fix typos in docstrings.
+ (org-html-do-expand): `org-export-html-convert-special-strings'
+ added to the list of conversion.
+ (org-infile-export-plist, org-get-current-options): Add support
+ for "-" in the #+OPTION line to let user switch on/off special
+ strings conversion.
+ (org-export-plist-vars): New :html-table-tag property.
+ (org-export-as-html, org-format-org-table-html)
+ (org-format-table-table-html) Use the :html-table-tag property
+ instead of the `org-export-html-table-tag' global value.
+ (org-additional-option-like-keywords): Add "TBLFM".
+ (org-entry-properties): Include the CLOCKSUM special property.
+ (org-columns-edit-value): Do not allow to edit the special
+ CLOCKSUM property.
+ (org-flag-drawer): Use the original value of `outline-regexp'.
+ (org-remember-handler): Add invisible-ok flag to call to
+ `org-end-of-subtree'.
+ (org-agenda-highlight-todo): Respect `org-agenda-todo-keyword-format'.
+ (org-infile-export-plist): No restriction while searching for
+ options.
+ (org-remember-handler): Remove comments at the end of the buffer.
+ (org-table-sort-lines): Make sure sorting works on link
+ descritions only, and ignores the link.
+ (org-sort-entries-or-items): Make sure the end of the subtree is
+ included.
+ (org-refile-use-outline-path): New allowed values `file' and
+ `full-file-path'.
+ (org-get-refile-targets): Respect new values for
+ `org-refile-use-outline-path'.
+ (org-agenda-get-restriction-and-command): DEL goes back to initial
+ list.
+ (org-export-as-xoxo): Restore point when done.
+ (org-open-file): Allow multiple %s in command.
+ (org-get-refile-targets): Interpret the new maxlevel setting.
+ (org-refile-targets): New option `:maxlevel'.
+ (org-copy-subtree): Include empty lines before but not after subtree.
+ (org-move-item-down, org-move-item-up): Include empty lines before
+ but not after item.
+ (org-remember-apply-template): Defaults, completions and history
+ for template prompts. Also, interpret new `%!' escape.
+ (org-context-choices): New constant.
+ (org-bound-and-true-p): New macro.
+ (org-agenda-restriction-lock): New face.
+ (org-open-at-point): Remove obsolete way to do redirection in
+ shell links.
+ (org-imenu-and-speedbar): New customization group.
+ (org-entry-properties): Return keyword-less time strings.
+ (org-clock-in): Use `org-clock-heading-function'.
+ (org-calendar-holiday): Try to use `calendar-check-holidays'
+ instead of the obsolete `check-calendar-holidays'.
+ (org-export-html-special-string-regexps): New constant.
+ (org-latex-and-export-specials): New face.
+ (org-link-escape-chars): Use characters instead of strings.
+ (org-link-escape-chars-browser, org-link-escape)
+ (org-link-unescape): Use characters instead of strings.
+ (org-export-html-convert-sub-super, org-html-do-expand): Check for
+ protected text.
+ (org-emphasis-alist): Additional `verbatim' flag.
+ (org-set-emph-re): Handle the verbatim flag and compute
+ `org-verbatim-re'.
+ (org-cleaned-string-for-export): Protect verbatim elements.
+ (org-additional-option-like-keywords): Add new keywords.
+ (org-get-entry): Rename from `org-get-cleaned-entry'.
+ (org-agenda-get-scheduled, org-agenda-get-blocks):
+ Use `org-agenda-skip-scheduled-if-done'.
+ (org-prepare-agenda-buffers): Allow buffers as arguments.
+ (org-entry-properties): Add CATEGORY as a special property.
+ (org-use-property-inheritance): Allow a list of properties as a value.
+ (org-eval-in-calendar): No longer update the prompt.
+ (org-read-date-popup-calendar): Rename from
+ `org-popup-calendar-for-date-prompt'.
+ (org-remember-apply-template): Define `remember-finalize' if it is
+ not yet defined.
+ (org-read-date): Respect the setting of
+ `org-read-date-prefer-future'. Use `org-read-date-analyze'.
+ (org-set-font-lock-defaults): Use `org-archive-tag' instead of a
+ hardcoded string.
+ (org-remember-apply-template): Use `remember-finalize' instead of
+ `remember-buffer'.
+ (org-columns-compute, org-column-number-to-string)
+ (org-columns-uncompile-format, org-columns-compile-format)
+ (org-columns-compile-format): Handle printf format specifier.
+ (org-columns-new, org-column-number-to-string)
+ (org-columns-uncompile-format, org-columns-compile-format):
+ Support for new currency summary type.
+ (org-tree-to-indirect-buffer): Do not kill old buffer when
+ `org-indirect-buffer-display' is `new-frame'.
+ (org-indirect-buffer-display): Document that `new-frame' leads to
+ indiret buffer proliferation.
+ (org-agenda-list): Use `org-extend-today-until'.
+ (org-format-org-table-html): Use lower-case for <col> tag.
+ (org-agenda-execute): New command.
+ (org-agenda-mode-map): Keybindings of "g" "G", "e" modified.
+ (org-remember-apply-template): Use `org-select-remember-template'.
+ (org-region-active-p): Use `use-region-p'.
+ (org-cycle-hide-archived-subtrees)
+ (org-table-rotate-recalc-marks, org-mark-ring-push)
+ (org-follow-info-link, org-mhe-get-message-folder-from-index)
+ (org-auto-repeat-maybe, org-store-log-note, org-delete-property)
+ (org-evaluate-time-range, org-edit-agenda-file-list):
+ (org-paste-subtree):
+ (org-calendar-holiday): Use calendar-check-holidays instead of the
+ obsolete check-calendar-holidays.
+ (org-table-formula-substitute-names): Remove forgotten temporary
+ debugging code.
+ (org-agenda-get-restriction-and-command): Use `mapc' instead of
+ `mapcar'.
+ (org-agenda-list): Numeric prefix argument can specify the number
+ of days.
+ (remember-register, remember-buffer): Prevent byte compiler from
+ complaining.
+ (org-todo): Save and restore match data.
+ (org-no-warnings): New macro.
+ (org-columns-eval): Use `org-no-warnings'.
+ (org-version): Change to 5.13e.
+ (org-agenda-file-regexp): Fix typo in docstring.
+ (org-add-planning-info): Fix bug in parenthesis settings.
+ (org-scan-tags): Catch the case of indirect buffers with no filename.
+ (org-fast-tag-selection, org-export-as-ascii, org-export-as-html):
+ Re-install switch to mapc, had been removed by accident.
+ (org-columns-map): New binding `C-c C-o'.
+ (org-columns-menu): Change menu text and added new entry.
+ (org-columns-eval): Document the use of `next-line'.
+ (org-columns-follow-link): Remove function.
+ (org-read-date-get-relative): Fix typo in docstring.
+ (org-read-date-get-relative): Leading +/- is not optional.
+ (org-agenda-get-restriction-and-command): Always resize window on
+ first loop cycle.
+ (org-agenda-open-link): Make sure the link abbreviations are
+ present in the agenda buffer.
+ (org-agenda-files): Allow directories in the variable.
+ (org-agenda): Use `org-agenda-get-restriction-and-command'.
+ (org-todo-blocker-hook, org-todo-trigger-hook): New hooks.
+ (org-remember-apply-template): Catch C-g and make sure window
+ configuration is restored.
+ (org-agenda-open-link): Make it work with several links in the line.
+ (org-drawers, org-set-regexps-and-options)
+ (org-get-current-options): Add support for a DRAWERS in-buffer option.
+ (org-fit-agenda-window): Use `org-agenda-window-frame-fractions'.
+ (org-agenda-to-appt): Require calendar.
+ (org-entry-get-with-inheritance): Widen for search.
+ (org-columns-display-here): Don't mark buffer as modified when
+ adding space characters to accomodate column overlays.
+ (org-export-as-html): Better formatting of tags in the toc.
+ (org-columns-display-here): Make the ITEM column as compact as
+ possible.
+ (org-remember-templates): Customization interface improved.
+ (org-export-with-property-drawer): Variable removed.
+ (org-sort-entries): Rewrite using `sort-subr'.
+ (org-set-property): More appropriate completion during interactive use.
+ (org-sort-entries): Allow sorting by property.
+ (org-additional-option-like-keywords): Add more values.
+ (org-sort-entries-or-items): Rename from `org-sort-entries'.
+ (org-at-timestamp-p, org-timestamp-change)
+ (org-remember-templates): First element of each entry is now a
+ name for the template.
+ (org-store-log-note): Check for `org-note-abort'.
+ (org-kill-note-or-show-branches): New command.
+ (org-cut-subtree, org-copy-subtree): New argument N to act on N
+ sequential subtrees.
+ (org-paste-subtree): Fix the level at which a tree is pasted.
+ (org-fit-agenda-window): Limitations on window size removed.
+ (org-agenda-find-same-or-today-or-agenda): Rename from
+ `org-agenda-find-today-or-agenda'.
+ (org-agenda-scheduled-leaders)
+ (org-agenda-get-deadlines): Use `org-agenda-deadline-leaders'.
+ (org-agenda-get-scheduled): Use `org-agenda-scheduled-leaders'.
+ (org-export-with-tags, org-export-plist-vars)
+ (org-infile-export-plist): New "tags" option.
+ (org-cached-entry-get): Use `org-use-property-inheritance'.
+ (org-remember-apply-template): Fix typo.
+ (org-additional-option-like-keywords): New constant.
+ (org-complete): Use `org-additional-option-like-keywords'.
+ (org-clock-report): Only update the table at point, or insert a
+ new one.
+ (org-open-file): Use `start-process-shell-command' instead of
+ `shell-command' with an ampersand.
+ (org-deadline, org-schedule): New argument REMOVE to remove the
+ date from the entry.
+ (org-agenda-schedule, org-agenda-deadline): Pass the prefix
+ argument to `org-schedule' and `org-deadline'.
+ (org-trim): Use the correct expressions for beginning and end of
+ the string.
+ (org-get-cleaned-entry): Trim the string before returning it.
+ (org-agenda-tags-column): Rename from
+ `org-agenda-align-tags-to-column'.
+ (org-agenda-align-tags): Allow negative values for
+ `org-agenda-tags-column'.
+ (org-insert-labeled-timestamps-before-properties-drawer): Remove var.
+ (org-agenda-to-appt): New optional argument FILTER.
+ (org-complete): Use `org-completion-fallback-command'.
+ (org-find-base-buffer-visiting): Catch the case that there is no
+ buffer visiting the file.
+ (org-todo): Use `org-property-or-variable-value'
+ (org-prepare-agenda, org-agenda-list): Use `org-agenda-compact-blocks'.
+ (org-agenda-schedule, org-agenda-deadline):
+ Call `org-agenda-show-new-time'.
+ (org-agenda-show-new-time): New argument PREFIX.
+ (org-colgroup-info-to-vline-list): Fix but that cause a shift in
+ the vertical lines.
+ (org-buffer-property-keys): New argument INCLUDE-DEFAULTS.
+ (org-maybe-renumber-ordered-list, org-cycle-list-bullet)
+ (org-indent-item): No arg in call to `org-fix-bullet-type'.
+ (org-fix-bullet-type): Remove argument.
+ (org-read-date): Check for am/pm twice, to catch the end time.
+ (org-goto-map): Use `suppress-keymap'.
+ (org-remember-apply-template): Respect the dynamically scoped
+ selection character.
+ (org-kill-is-subtree-p): Use `org-outline-regexp'.
+ (org-outline-regexp): New constant.
+ (org-remember-handler): Throw error when the target file is not in
+ org-mode.
+ (org-cleaned-string-for-export): No longer call
+ `org-export-latex-cleaned-string' with an argument.
+ (org-get-tags): Returns now a list, not a string.
+ (org-archive-subtree): No need to split return of `org-get-tags'.
+ (org-set-tags, org-entry-properties): Call `org-get-tags-string'
+ instead of `org-get-tags'.
+ (org-agenda-format-date): Rename from `org-agenda-date-format'.
+ (org-time-from-absolute, org-agenda-format-date-aligned): New funs.
+ (org-compatible-face): New argument INHERITS. Inherit from this
+ face if possible.
+ (org-level-1, org-level-2, org-level-3, org-level-4)
+ (org-level-5, org-level-6, org-level-7, org-level-8)
+ (org-special-keyword, org-drawer, org-column, org-warning)
+ (org-archived, org-todo, org-done, org-headline-done, org-table)
+ (org-formula, org-code, org-agenda-structure)
+ (org-scheduled-today, org-scheduled-previously)
+ (org-upcoming-deadline, org-time-grid): Call `org-compatible-face'
+ in the new way.
+ (org-get-heading): New argument NO-TAGS.
+ (org-fast-tag-selection-include-todo): Made defvar instead of
+ defcustom, feature is not deprecated.
+ (org-remember-store-without-prompt): New default value t.
+ (org-set-regexps-and-options): #+TODO is an alias for SEQ_TODO.
+ Compute the log states.
+ (org-goto-map): More commands copied from global map. Also bind
+ `org-occur'.
+ (org-goto): Made into a general lookup command.
+ (org-get-location): Complete rewrite.
+ (org-goto-ret, org-goto-left, org-goto-right, org-goto-quit):
+ Set the new variables.
+ (org-paste-subtree): Whitespace insertion strategy revised.
+ (org-remember-apply-template): Protect v-A from the possibility
+ that v-a might be nil.
+ (org-remember-handler): Insertion rules revised.
+ (org-todo): Respect org-todo-log-states.
+ (org-entry-get-with-inheritance): Use `org-up-heading-safe'.
+ (org-confirm-shell-link-function)
+ (org-confirm-elisp-link-function): Doc fixes.
+ (org-re): Also replace the :alpha: class.
+ (org-todo-tag-alist): Variable removed.
+ (org-log-done): Docstring fixed.
+ (org-deadline-warning-days): New default value 14.
+ (org-tag-alist): Docstring fixed.
+ (org-export-language-setup): New languages added.
+ (org-set-regexps-and-options): Compute the new variables.
+ (org-paste-subtree): Cleaning up.
+ (org-remember-apply-template): New escape %A.
+ (org-todo): Call fast TODO selection.
+ (org-add-log-note): Allow prefix for abort exit.
+ (org-at-property-p, org-entry-properties)
+ (org-columns-get-autowidth-alist): Use :alpha: class.
+ (org-agenda-get-deadlines): Use `org-get-wdays'.
+ (org-agenda-get-deadlines): Reverse ee before returning.
+ (org-format-agenda-item): New argument REMOVE-RE.
+ (org-agenda-convert-date): Baha'i calendar added.
+ (org-infile-export-plist): Also find DATE line.
+ (org-export-as-html, org-export-as-ascii): Use the date format.
+ (org-shiftup, org-shiftdown): Use.
+ `org-edit-timestamp-down-means-later'.
+ (org-columns-compile-format)
+ (org-columns-get-autowidth-alist, org-buffer-property-keys)
+ (org-entry-properties, org-at-property-p): Allow [:alnum:] in
+ property names.
+ (org-export-visible): Fix drawers before export.
+ (org-do-sort): Allow sorting by priority.
+ (org-agenda-files): Ignore non-existing files.
+ (org-ellipsis): All a face as value.
+ (org-mode): Interprete the face value of `org-ellipsis'.
+ (org-archive-subtree): Store context info in archived entry.
+ (org-fast-tag-selection): Allow setting TODO states through this
+ interface.
+ (org-cycle): Docstring updated.
+ (org-set-font-lock-defaults, org-agenda-highlight-todo):
+ Use `org-get-todo-face'.
+ (org-table-edit-field, org-table-show-reference)
+ (org-table-edit-formulas, org-add-log-note)
+ (org-fast-tag-selection, org-agenda, org-prepare-agenda)
+ (org-timeline): Use `org-switch-to-buffer-other-window' instead of
+ `switch-to-buffer-other-window' to make sure that the temporary
+ windows show up on the current frame.
+ (org-mhe-get-message-real-folder, org-batch-store-agenda-views)
+ (org-get-entries-from-diary, org-replace-region-by-html):
+ Don't allow pop-up frames.
+ (org-agenda-get-deadlines, org-agenda-get-scheduled): Fix problems
+ with time-of-day.
+ (org-agenda-get-scheduled, org-agenda-get-deadlines): Fix problems
+ with listing items that are DONE.
+ (org-change-tag-in-region): New command.
+ (org-agenda-skip-scheduled-if-done)
+ (org-agenda-skip-deadline-if-done): Docstring clarified.
+ (org-mode): Hide drawers on startup.
+ (org-set-regexps-and-options): Use `org-remove-keyword-keys'.
+ (org-agenda-skip): Allow a form for `org-agenda-skip-function'.
+ (org-agenda-redo): Re-use local settings.
+ (org-agenda): Store local settings.
+ (org-agenda-get-deadlines, org-agenda-get-scheduled): Also handle
+ entries on their due date.
+ (org-agenda-get-timestamps): No longer handle the due dates of
+ schedules and deadline items.
+ (org-insert-link-global, org-open-at-point-global): New commands.
+ (org-export-as-ascii): Call `org-cleaned-string-for-export' with a
+ :for-ascii parameter.
+ (org-skip-comments): Function removed.
+ (org-cleaned-string-for-export): Handle special table lines.
+ (org-entry-get-with-inheritance): Check global properties.
+ (org-set-regexps-and-options): Find the #+PROPERTY line.
+ (org-link-types): Change type into variable (was constant).
+ (org-link-re-with-space, org-link-re-with-space2)
+ (org-angle-link-re, org-plain-link-re, org-bracket-link-regexp)
+ (org-bracket-link-analytic-regexp, org-any-link-re): Creation of
+ these regular expressions happens now in the function
+ `org-make-link-regexps'.
+ (org-store-link): Call the functions in
+ `org-store-link-functions'.
+ (org-activate-tags): Force matches to be in headlines.
+ (org-batch-store-agenda-views): Fix bug with killing agenda buffer.
+ (org-columns-display-here): Make sure this works in a narrowed
+ buffer by checking for point-min.
+ (org-columns-display-here): Make the rest of the line intangible,
+ so that point never can be there.
+ (org-cleaned-string-for-export): Use `with-current-buffer'.
+ (org-replace-region-by-html): Use `with-current-buffer'.
+ (org-unfontify-region, org-do-occur, org-columns-display-here)
+ (org-columns-remove-overlays, org-columns-quit)
+ (org-columns-edit-value, org-columns-next-allowed-value)
+ (org-eval-in-calendar, org-agenda-undo, org-no-read-only)
+ (org-finalize-agenda, org-remove-subtree-entries-from-agenda)
+ (org-agenda-todo, org-agenda-change-all-lines)
+ (org-agenda-align-tags, org-agenda-priority)
+ (org-agenda-set-tags, org-agenda-toggle-archive-tag)
+ (org-agenda-show-new-time, org-cleaned-string-for-export)
+ (org-export-grab-title-from-buffer)
+ (org-export-as-ascii, org-export-as-html): Use `inhibit-read-only'
+ instead of `buffer-read-only'.
+ (org-export-as-html): Set `coding-system-for-write'.
+ (org-archive-subtree): Fix bug with modifying TODO keyword.
+ (org-beginning-of-line): Also treat C-a special in items.
+ (org-table-convert-refs-to-rc): Fix problem with column
+ reference after "..".
+ (org-columns-compute): Don't mark buffer modified because of text
+ properties.
+ (org-batch-store-agenda-views): Use the variable
+ `default-directory', not the function.
+ (org-clock-out-if-current): Respect `org-clock-out-when-done'.
+ (org-html-entities): Add HTML entities for smileys.
+ (org-end-of-line): Move to end of line if in headline without tags.
+ (org-agenda-day-view, org-agenda-week-view): Remember span as default.
+ (org-columns-edit-value): Rename from `org-column-edit'.
+ (org-columns-display-here-title): Rename from
+ `org-overlay-columns-title'.
+ (org-columns-remove-overlays): Rename from
+ org-remove-column-overlays.
+ (org-columns-get-autowidth-alist): Rename from
+ `org-get-columns-autowidth-alist'.
+ (org-columns-display-here): Rename from `org-overlay-columns'.
+ (org-columns-new-overlay): Rename from `org-new-column-overlay'.
+ (org-columns-quit): Rename from `org-column-quit'.
+ (org-columns-show-value): Rename from `org-column-show-value'.
+ (org-columns-current-fmt): Rename from `org-current-columns-fmt'.
+ (org-columns-overlays): Rename from `org-column-overlays'.
+ (org-columns-map): Rename from `org-column-map'.
+ (org-columns-current-maxwidths): Rename from
+ `org-current-columns-maxwidths'.
+ (org-columns-begin-marker, org-columns-current-fmt-compiled)
+ (org-previous-header-line-format)
+ (org-columns-inhibit-recalculation)
+ (org-columns-default-format): Rename from
+ `org-default-columns-format'.
+ (org-property-re): New constant.
+ (orgstruct-mode): New minor mode.
+ (org-cycle-list-bullet): New command.
+ (org-special-properties, org-property-start-re)
+ (org-property-end-re): New constants.
+ (org-with-point-at): New macro.
+ (org-insert-property-drawer): New command.
+ (org-column): New face.
+ (org-column-menu): New menu.
+ (org-columns, org-agenda-columns): New commands.
+ (org-properties): New customize group.
+ (org-priority): Realign tags after changing priority.
+ (org-preserve-lc): New macro.
+ (org-update-checkbox-count): Catch case when there is no headline.
+ (org-agenda-quit): Remove any column overlays.
+ (org-beginning-of-item-list): Fix bug when non-item line is
+ indented too deep.
+ (org-make-tags-matcher): Handle property matches.
+ (org-table-recalculate): Swap evaluation order: Field formula
+ first, then column formulas, but don't allow them to overwrite the
+ field formulas.
+ (org-table-eval-formula): New argument untouchable.
+ (org-export-as-html): Fix replacement bug for XEmacs.
+
+2008-04-06 Chong Yidong <cyd@stupidchicken.com>
+
+ * dired.el (dired-dnd-handle-local-file):
+ Obey dired-backup-overwrite for copy, move, and link operations.
+
+ * dired-aux.el (dired-overwrite-confirmed): Undo last change.
+
+2008-04-06 Alan Mackenzie <acm@muc.de>
+
+ * progmodes/cc-langs.el (c-before-font-lock-function): Correct a
+ typo in the doc string.
+
+ * progmodes/cc-mode.el (c-extend-after-change-region):
+ New function, used in font-lock-extend-after-change-region-function,
+ thus superseding advice on the Font Lock after change functions.
+
+2008-04-06 Chong Yidong <cyd@stupidchicken.com>
+
+ * dired-aux.el (dired-overwrite-confirmed): Supply initial value.
+
+2008-04-04 Stephen Berman <Stephen.Berman@gmx.net>
+
+ * newcomment.el (comment-enter-backward): Be careful to restore
+ position changed during narrowing.
+
+2008-04-03 Nick Roberts <nickrob@snap.net.nz>
+
+ * progmodes/gdb-ui.el (gdb-mouse-set-clear-breakpoint):
+ Fix in disassembly buffer (regression in 22.2).
+
+2008-04-03 Chong Yidong <cyd@stupidchicken.com>
+
+ * shell.el (shell-dynamic-complete-filename): New fun.
+ (shell-dynamic-complete-functions): Use it.
+
+2008-04-02 Alan Mackenzie <acm@muc.de>
+
+ * progmodes/cc-cmds.el (c-defun-name, c-cpp-define-name):
+ New optimised functions to get the name of the current defun/macro.
+
+ * add-log.el (add-log-current-defun): Move the functionality which
+ gets the current function name for C like modes to cc-cmds.el,
+ thus optimising for speed.
+
+2008-04-02 Eli Zaretskii <eliz@gnu.org>
+
+ * ps-print.el (ps-generate-postscript-with-faces): If the face
+ specified by the overlay's `face' property is a string, assume
+ it's a string name and intern it to get the face symbol.
+
+2008-04-01 Chong Yidong <cyd@stupidchicken.com>
+
+ * find-dired.el (find-dired-filter): Fix last patch to handle
+ multi-line process input. Pad link numbers too.
+
+2008-04-01 Jari Aalto <jari.aalto@cante.net>
+
+ * find-dired.el (find-dired-filter): Align columns by padding file
+ sizes.
+
+2008-04-01 Jay Belanger <jay.p.belanger@gmail.com>
+
+ * calc/calc.el: Autoload `calc-yank'.
+ (calc-mode-map): Add keybindings for `calc-yank'.
+ * calc/calc-ext.el (calc-init-extensions): Remove keybinding
+ assignments for `calc-yank'.
+
+2008-03-31 Martin Rudalics <rudalics@gmx.at>
+
+ * emacs-lisp/find-func.el (find-function-search-for-symbol):
+ Strip extension from .emacs.el to make sure symbol is searched
+ in .emacs too.
+
+2008-03-29 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * vc.el (vc-do-command): Don't show internal temp buffers.
+
+2008-03-29 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * term/mac-win.el (mac-ae-reopen-application): New function.
+ (mac-apple-event-map): Bind "reopen application" Apple event to it.
+
+2008-03-29 Juanma Barranquero <lekktu@gmail.com>
+
+ * term/mac-win.el (mac-dnd-drop-data): Remove redundant check.
+
2008-03-26 Chong Yidong <cyd@stupidchicken.com>
* Version 22.2 released.
2008-03-23 Andreas Schwab <schwab@suse.de>
- * menu-bar.el (menu-bar-showhide-fringe-ind-menu) [mixed]: Fix
- radio button condition.
+ * menu-bar.el (menu-bar-showhide-fringe-ind-menu) [mixed]:
+ Fix radio button condition.
[box]: Likewise.
[customize]: Add radio button.
2008-03-19 Wilson Snyder <wsnyder@wsnyder.org>
- * progmodes/verilog-mode.el (verilog-easy-menu-filter): New
- function.
+ * progmodes/verilog-mode.el (verilog-easy-menu-filter):
+ New function.
(verilog-stmt-menu, verilog-menu): Add :help.
(verilog-customize, verilog-font-customize)
(electric-verilog-backward-sexp, electric-verilog-forward-sexp)
(verilog-auto-search-do, verilog-auto-re-search-do)
(verilog-skip-forward-comment-or-string): Fix verilog-auto
expansion when a .* appears inside a string.
- (verilog-re-search-forward, verilog-re-search-backward): Add
- comment to recall how this works.
+ (verilog-re-search-forward, verilog-re-search-backward):
+ Add comment to recall how this works.
2008-03-19 Reiner Steib <Reiner.Steib@gmx.de>
bootstrap-prepare:
if test -x $(EMACS); then \
- $(MAKE) $(MFLAGS) autoloads; \
+ $(MAKE) $(MFLAGS) autoloads EMACS=$(EMACS); \
else \
cp $(lisp)/ldefs-boot.el $(lisp)/loaddefs.el; \
fi
(buffer-substring-no-properties (point)
(progn (forward-sexp 1)
(point)))))
- ((and (memq major-mode add-log-c-like-modes)
- (save-excursion
- (beginning-of-line)
- ;; Use eq instead of = here to avoid
- ;; error when at bob and char-after
- ;; returns nil.
- (while (eq (char-after (- (point) 2)) ?\\)
- (forward-line -1))
- (looking-at "[ \t]*#[ \t]*define[ \t]")))
- ;; Handle a C macro definition.
- (beginning-of-line)
- (while (eq (char-after (- (point) 2)) ?\\) ;not =; note above
- (forward-line -1))
- (search-forward "define")
- (skip-chars-forward " \t")
- (buffer-substring-no-properties (point)
- (progn (forward-sexp 1)
- (point))))
((memq major-mode add-log-c-like-modes)
- ;; See whether the point is inside a defun.
- (let (having-previous-defun
- having-next-defun
- previous-defun-end
- next-defun-beginning)
-
- (save-excursion
- (setq having-previous-defun
- (c-beginning-of-defun))
- (c-end-of-defun)
- ;; `c-end-of-defun' moves point to the line after
- ;; the function close, but the position we prefer
- ;; here is the position after the final }.
- (backward-sexp 1)
- (forward-sexp 1)
- ;; Skip the semicolon ``;'' for
- ;; enum/union/struct/class definition.
- (if (= (char-after (point)) ?\;)
- (forward-char 1))
- (setq previous-defun-end (point)))
-
- (save-excursion
- (setq having-next-defun
- (c-end-of-defun))
- (c-beginning-of-defun)
- (setq next-defun-beginning (point)))
-
- (if (and having-next-defun
- (< location next-defun-beginning))
- (skip-syntax-forward " "))
- (if (and having-previous-defun
- (> location previous-defun-end))
- (skip-syntax-backward " "))
- (unless (or
- ;; When there is no previous defun, the
- ;; point is not in a defun if it is not at
- ;; the beginning of the next defun.
- (and (not having-previous-defun)
- (not (= (point)
- next-defun-beginning)))
- ;; When there is no next defun, the point
- ;; is not in a defun if it is not at the
- ;; end of the previous defun.
- (and (not having-next-defun)
- (not (= (point)
- previous-defun-end)))
- ;; If the point is between two defuns, it
- ;; is not in a defun.
- (and (> (point) previous-defun-end)
- (< (point) next-defun-beginning)))
- ;; If the point is already at the beginning of a
- ;; defun, there is no need to move point again.
- (if (not (= (point) next-defun-beginning))
- (c-beginning-of-defun))
- ;; Is this a DEFUN construct? And is LOCATION in it?
- (if (and (looking-at "DEFUN\\b")
- (>= location (point)))
- ;; DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory, ...) ==> Ffile_name_directory
- ;; DEFUN(POSIX::STREAM-LOCK, stream lockp &key BLOCK SHARED START LENGTH) ==> POSIX::STREAM-LOCK
- (progn
- (down-list 1)
- (when (= (char-after (point)) ?\")
- (forward-sexp 1)
- (search-forward ","))
- (skip-syntax-forward " ")
- (buffer-substring-no-properties
- (point)
- (progn (search-forward ",")
- (forward-char -1)
- (skip-syntax-backward " ")
- (point))))
- (if (looking-at "^[+-]")
- ;; Objective-C
- (change-log-get-method-definition)
- ;; Ordinary C function syntax.
- (let ((beg (point)))
- (if (and
- ;; Protect against "Unbalanced parens" error.
- (condition-case nil
- (progn
- (down-list 1) ; into arglist
- (backward-up-list 1)
- (skip-chars-backward " \t")
- t)
- (error nil))
- ;; Verify initial pos was after
- ;; real start of function.
- (save-excursion
- (goto-char beg)
- ;; For this purpose, include the line
- ;; that has the decl keywords. This
- ;; may also include some of the
- ;; comments before the function.
- (while (and (not (bobp))
- (save-excursion
- (forward-line -1)
- (looking-at "[^\n\f]")))
- (forward-line -1))
- (>= location (point)))
- ;; Consistency check: going down and up
- ;; shouldn't take us back before BEG.
- (> (point) beg))
- (let (end middle)
- ;; Don't include any final whitespace
- ;; in the name we use.
- (skip-chars-backward " \t\n")
- (setq end (point))
- (backward-sexp 1)
- ;; Now find the right beginning of the name.
- ;; Include certain keywords if they
- ;; precede the name.
- (setq middle (point))
- ;; We tried calling `forward-sexp' in a loop
- ;; but it causes inconsistency for C names.
- (forward-sexp -1)
- ;; Is this C++ method?
- (when (and (< 2 middle)
- (string= (buffer-substring (- middle 2)
- middle)
- "::"))
- ;; Include "classname::".
- (setq middle (point)))
- ;; Ignore these subparts of a class decl
- ;; and move back to the class name itself.
- (while (looking-at "public \\|private ")
- (skip-chars-backward " \t:")
- (setq end (point))
- (backward-sexp 1)
- (setq middle (point))
- (forward-word -1))
- (and (bolp)
- (looking-at
- "enum \\|struct \\|union \\|class ")
- (setq middle (point)))
- (goto-char end)
- (when (eq (preceding-char) ?=)
- (forward-char -1)
- (skip-chars-backward " \t")
- (setq end (point)))
- (buffer-substring-no-properties
- middle end)))))))))
+ (or (c-cpp-define-name)
+ (c-defun-name)))
((memq major-mode add-log-tex-like-modes)
(if (re-search-backward
"\\\\\\(sub\\)*\\(section\\|paragraph\\|chapter\\)"
(define-key calc-mode-map "\M-k" 'calc-copy-as-kill)
(define-key calc-mode-map "\C-w" 'calc-kill-region)
(define-key calc-mode-map "\M-w" 'calc-copy-region-as-kill)
- (define-key calc-mode-map "\C-y" 'calc-yank)
- (define-key calc-mode-map [mouse-2] 'calc-yank)
(define-key calc-mode-map "\C-_" 'calc-undo)
(define-key calc-mode-map "\C-xu" 'calc-undo)
(define-key calc-mode-map "\M-\C-m" 'calc-last-args)
(and un ud
(if (and (equal (nth 4 un) (nth 4 ud))
(eq pow1 pow2))
- (math-to-standard-units (list '/ n d) nil)
+ (if (eq pow1 1)
+ (math-to-standard-units (list '/ n d) nil)
+ (list '^ (math-to-standard-units (list '/ n d) nil) pow1))
(let (ud1)
(setq un (nth 4 un)
ud (nth 4 ud))
(define-key map "\C-m" 'calc-enter)
(define-key map "\M-\C-m" 'calc-last-args-stub)
(define-key map "\C-j" 'calc-over)
+ (define-key map "\C-y" 'calc-yank)
+ (define-key map [mouse-2] 'calc-yank)
(mapc (lambda (x) (define-key map (char-to-string x) 'undefined))
"lOW")
calc-missing-key calc-mod calc-other-window calc-over calc-percent
calc-pop-above calc-power calc-roll-down calc-roll-up
calc-shift-Y-prefix-help calc-tutorial calcDigit-letter
- report-calc-bug)))
+ report-calc-bug)
+
+ ("calc-yank" calc-yank)))
;;;###autoload (define-key ctl-x-map "*" 'calc-dispatch)
(* 365 (1- year)) ; Days in prior years.
leap-days
(calendar-sum m 1 (< m month) 19)
- (if (= month 19) 4 0)
+ (if (= month 19)
+ (if (bahai-calendar-leap-year-p year) 5 4)
+ 0)
day))) ; Days so far this month.
(defun calendar-bahai-from-absolute (date)
(y (extract-calendar-year bahai-date))
(m (extract-calendar-month bahai-date))
(d (extract-calendar-day bahai-date)))
- (let ((monthname
- (if (and (= m 19)
- (<= d 0))
- "Ayyam-i-Ha"
- (aref bahai-calendar-month-name-array (1- m))))
- (day (int-to-string
- (if (<= d 0)
- (if (bahai-calendar-leap-year-p y)
- (+ d 5)
- (+ d 4))
- d)))
- (dayname nil)
- (month (int-to-string m))
- (year (int-to-string y)))
- (mapconcat 'eval calendar-date-display-form ""))))
+ (if (< y 1)
+ "" ; pre-Bahai
+ (let ((monthname
+ (if (and (= m 19)
+ (<= d 0))
+ "Ayyam-i-Ha"
+ (aref bahai-calendar-month-name-array (1- m))))
+ (day (int-to-string
+ (if (<= d 0)
+ (if (bahai-calendar-leap-year-p y)
+ (+ d 5)
+ (+ d 4))
+ d)))
+ (dayname nil)
+ (month (int-to-string m))
+ (year (int-to-string y)))
+ (mapconcat 'eval calendar-date-display-form "")))))
(defun calendar-print-bahai-date ()
"Show the Baha'i calendar equivalent of the selected date."
(interactive)
- (message "Baha'i date: %s"
- (calendar-bahai-date-string (calendar-cursor-to-date t))))
+ (let ((s (calendar-bahai-date-string (calendar-cursor-to-date t))))
+ (if (string-equal s "")
+ (message "Date is pre-Baha'i")
+ (message "Baha'i date: %s" s))))
(defun calendar-goto-bahai-date (date &optional noecho)
"Move cursor to Baha'i date DATE.
(defun holiday-bahai (month day string)
"Holiday on MONTH, DAY (Baha'i) called STRING.
-If MONTH, DAY (Baha'i) is visible, the value returned is corresponding
-Gregorian date in the form of the list (((month day year) STRING)). Returns
-nil if it is not visible in the current calendar window."
+If MONTH, DAY (Baha'i) is visible in the current calendar window,
+returns the corresponding Gregorian date in the form of the
+list (((month day year) STRING)). Otherwise, returns nil."
+ ;; Since the calendar window shows 3 months at a time, there are
+ ;; approx +/- 45 days either side of the central month.
+ ;; Since the Bahai months have 19 days, this means up to +/- 3 months.
(let* ((bahai-date (calendar-bahai-from-absolute
(calendar-absolute-from-gregorian
(list displayed-month 15 displayed-year))))
(m (extract-calendar-month bahai-date))
(y (extract-calendar-year bahai-date))
- (date))
- (if (< m 1)
- nil ;; Baha'i calendar doesn't apply.
- (increment-calendar-month m y (- 10 month))
- (if (> m 7) ;; Baha'i date might be visible
- (let ((date (calendar-gregorian-from-absolute
- (calendar-absolute-from-bahai (list month day y)))))
- (if (calendar-date-is-visible-p date)
- (list (list date string))))))))
+ date)
+ (unless (< m 1) ; Baha'i calendar doesn't apply
+ ;; Cf holiday-fixed, holiday-islamic.
+ ;; With a +- 3 month calendar window, and 19 months per year,
+ ;; month 16 is special. When m16 is central is when the
+ ;; end-of-year first appears. When m1 is central, m16 is no
+ ;; longer visible. Hence we can do a one-sided test to see if
+ ;; m16 is visible. m16 is visible when the central month >= 13.
+ ;; To see if other months are visible we can shift the range
+ ;; accordingly.
+ (increment-calendar-month m y (- 16 month) 19)
+ (and (> m 12) ; Baha'i date might be visible
+ (calendar-date-is-visible-p
+ (setq date (calendar-gregorian-from-absolute
+ (calendar-absolute-from-bahai (list month day y)))))
+ (list (list date string))))))
(defun list-bahai-diary-entries ()
"Add any Baha'i date entries from the diary file to `diary-entries-list'.
entry
(if (= y d) "" " (evening)")
diff
- (cond ((= (% diff 10) 1) "st")
- ((= (% diff 10) 2) "nd")
- ((= (% diff 10) 3) "rd")
- (t "th")))))))
+ (diary-ordinal-suffix diff))))))
(defun diary-rosh-hodesh (&optional mark)
"Rosh Hodesh diary entry.
(defun holiday-islamic (month day string)
"Holiday on MONTH, DAY (Islamic) called STRING.
-If MONTH, DAY (Islamic) is visible, the value returned is corresponding
-Gregorian date in the form of the list (((month day year) STRING)). Returns
-nil if it is not visible in the current calendar window."
+If MONTH, DAY (Islamic) is visible, returns the corresponding
+Gregorian date as the list (((month day year) STRING)).
+Returns nil if it is not visible in the current calendar window."
(let* ((islamic-date (calendar-islamic-from-absolute
(calendar-absolute-from-gregorian
(list displayed-month 15 displayed-year))))
(julian-end (calendar-julian-from-absolute end-date))
(julian-y1 (extract-calendar-year julian-start))
(julian-y2 (extract-calendar-year julian-end)))
- (setq year (if (< 10 month) julian-y1 julian-y2))
+ (setq year (if (<= 10 month) julian-y1 julian-y2))
(let ((date (calendar-gregorian-from-absolute
(calendar-absolute-from-julian
(list month day year)))))
"A string giving extra LaTeX commands to insert in the calendar preamble.
For example, to include extra packages:
\"\\\\usepackage{foo}\\n\\\\usepackage{bar}\\n\"."
- :type 'string
+ :type '(choice (const nil) string)
:group 'calendar-tex
:version "22.1")
(defconst lunar-phases-buffer "*Phases of Moon*"
"Name of the buffer used for the lunar phases.")
-(defmacro increment-calendar-month (mon yr n)
+(defmacro increment-calendar-month (mon yr n &optional nmonths)
"Increment the variables MON and YR by N months.
Forward if N is positive or backward if N is negative.
-A negative YR is interpreted as BC; -1 being 1 BC, and so on."
- `(let (macro-y)
+A negative YR is interpreted as BC; -1 being 1 BC, and so on.
+Optional NMONTHS is the number of months per year (default 12)."
+ `(let ((nmonths (or ,nmonths 12))
+ macro-y)
(if (< ,yr 0) (setq ,yr (1+ ,yr))) ; -1 BC -> 0 AD, etc
- (setq macro-y (+ (* ,yr 12) ,mon -1 ,n)
- ,mon (1+ (mod macro-y 12))
- ,yr (/ macro-y 12))
+ (setq macro-y (+ (* ,yr nmonths) ,mon -1 ,n)
+ ,mon (1+ (mod macro-y nmonths))
+ ,yr (/ macro-y nmonths))
(and (< macro-y 0) (> ,mon 1) (setq ,yr (1- ,yr)))
(if (< ,yr 1) (setq ,yr (1- ,yr))))) ; 0 AD -> -1 BC, etc
(- date (% (- date dayname) 7)))
(defun calendar-nth-named-absday (n dayname month year &optional day)
- "The absolute date of Nth DAYNAME in MONTH, YEAR before/after optional DAY.
-A DAYNAME of 0 means Sunday, 1 means Monday, and so on. If N<0,
-return the Nth DAYNAME before MONTH DAY, YEAR (inclusive).
+ "Absolute date of the Nth DAYNAME after/before MONTH YEAR DAY.
+A DAYNAME of 0 means Sunday, 1 means Monday, and so on.
If N>0, return the Nth DAYNAME after MONTH DAY, YEAR (inclusive).
-
-If DAY is omitted, it defaults to 1 if N>0, and MONTH's last day otherwise."
+If N<0, return the Nth DAYNAME before MONTH DAY, YEAR (inclusive).
+DAY defaults to 1 if N>0, and MONTH's last day otherwise."
(if (> n 0)
(+ (* 7 (1- n))
(calendar-dayname-on-or-before
year))))))
(defun calendar-nth-named-day (n dayname month year &optional day)
- "The date of Nth DAYNAME in MONTH, YEAR before/after optional DAY.
-A DAYNAME of 0 means Sunday, 1 means Monday, and so on. If N<0,
-return the Nth DAYNAME before MONTH DAY, YEAR (inclusive).
-If N>0, return the Nth DAYNAME after MONTH DAY, YEAR (inclusive).
-
-If DAY is omitted, it defaults to 1 if N>0, and MONTH's last day otherwise."
+ "Date of the Nth DAYNAME after/before MONTH YEAR DAY.
+Like `calendar-nth-named-absday', but returns a Gregorian date."
(calendar-gregorian-from-absolute
(calendar-nth-named-absday n dayname month year day)))
(msg (format "No diary entries for %s" hol-string))
;; If selected window is dedicated (to the calendar),
;; need a new one to display the diary.
- (pop-up-frames (window-dedicated-p (selected-window))))
+ (pop-up-frames (or pop-up-frames
+ (window-dedicated-p (selected-window)))))
(calendar-set-mode-line (format "Diary for %s" hol-string))
(if (or (not diary-entries-list)
(and (not (cdr diary-entries-list))
is created."
(interactive)
(let ((d-file (diary-check-diary-file))
- (pop-up-frames (window-dedicated-p (selected-window))))
+ (pop-up-frames (or pop-up-frames
+ (window-dedicated-p (selected-window)))))
(with-current-buffer (or (find-buffer-visiting d-file)
(find-file-noselect d-file t))
(when (eq major-mode default-major-mode) (diary-mode))
when highlighting the day in the calendar.
%%(diary-float MONTH DAYNAME N &optional DAY MARK) text
- Entry will appear on the Nth DAYNAME of MONTH.
+ Entry will appear on the Nth DAYNAME after/before MONTH DAY.
(DAYNAME=0 means Sunday, 1 means Monday, and so on;
if N is negative it counts backward from the end of
the month. MONTH can be a list of months, a single
(cons mark entry))))
(defun diary-float (month dayname n &optional day mark)
- "Floating diary entry--entry applies if date is the nth dayname of month.
-Parameters are MONTH, DAYNAME, N. MONTH can be a list of months, the constant
-t, or an integer. The constant t means all months. If N is negative, count
-backward from the end of the month.
-
-An optional parameter DAY means the Nth DAYNAME on or after/before MONTH DAY.
+ "Diary entry for the Nth DAYNAME after/before MONTH DAY.
+DAYNAME=0 means Sunday, DAYNAME=1 means Monday, and so on.
+If N>0, use the Nth DAYNAME after MONTH DAY.
+If N<0, use the Nth DAYNAME before MONTH DAY.
+DAY defaults to 1 if N>0, and MONTH's last day otherwise.
+MONTH can be a list of months, an integer, or `t' (meaning all months).
Optional MARK specifies a face or single-character string to use when
highlighting the day in the calendar."
;; This is messy because the diary entry may apply, but the date on which it
SEXP is a diary-sexp. DAYS is either a single number or a list of numbers
indicating the number(s) of days before the event that the warning(s) should
occur on. If the current date is (one of) DAYS before the event indicated by
-SEXP, then a suitable message (as specified by `diary-remind-message' is
+SEXP, then a suitable message (as specified by `diary-remind-message') is
returned.
In addition to the reminders beforehand, the diary entry also appears on the
"Insert a diary entry STRING which may be NONMARKING in FILE.
If omitted, NONMARKING defaults to nil and FILE defaults to
`diary-file'."
- (let ((pop-up-frames (window-dedicated-p (selected-window))))
+ (let ((pop-up-frames (or pop-up-frames
+ (window-dedicated-p (selected-window)))))
(find-file-other-window (substitute-in-file-name (or file diary-file))))
(when (eq major-mode default-major-mode) (diary-mode))
(widen)
(list (list (list month day y) string)))))
(defun holiday-float (month dayname n string &optional day)
- "Holiday on MONTH, DAYNAME (Nth occurrence) called STRING.
-If the Nth DAYNAME in MONTH is visible, the value returned is the list
-\(((MONTH DAY year) STRING)).
-
-If N<0, count backward from the end of MONTH.
-
-An optional parameter DAY means the Nth DAYNAME on or after/before MONTH DAY.
-
-Returns nil if it is not visible in the current calendar window."
+ "Holiday called STRING on the Nth DAYNAME after/before MONTH DAY.
+DAYNAME=0 means Sunday, DAYNAME=1 means Monday, and so on.
+If N>0, use the Nth DAYNAME after MONTH DAY.
+If N<0, use the Nth DAYNAME before MONTH DAY.
+DAY defaults to 1 if N>0, and MONTH's last day otherwise.
+If the holiday is visible in the calendar window, returns a
+list (((month day year) STRING)). Otherwise returns nil."
;; This is messy because the holiday may be visible, while the date on which
;; it is based is not. For example, the first Monday after December 30 may be
;; visible when January is not. For large values of |n| the problem is more
(require 'cus-face)
(defvar generated-custom-dependencies-file "cus-load.el"
- "Output file for \\[custom-make-dependencies].")
+ "Output file for `custom-make-dependencies'.")
(defun custom-make-dependencies ()
"Batch function to extract custom dependencies from .el files.
(recentf-expand-file-name (custom-file)))
"\\'")
recentf-exclude)))
- (old-buffer (find-buffer-visiting filename)))
+ (old-buffer (find-buffer-visiting filename))
+ old-buffer-name)
(with-current-buffer (let ((find-file-visit-truename t))
(or old-buffer (find-file-noselect filename)))
+ ;; We'll save using file-precious-flag, so avoid destroying
+ ;; symlinks. (If we're not already visiting the buffer, this is
+ ;; handled by find-file-visit-truename, above.)
+ (when old-buffer
+ (setq old-buffer-name (buffer-file-name))
+ (set-visited-file-name (file-chase-links filename)))
+
(unless (eq major-mode 'emacs-lisp-mode)
(emacs-lisp-mode))
(let ((inhibit-read-only t))
(custom-save-faces))
(let ((file-precious-flag t))
(save-buffer))
- (unless old-buffer
+ (if old-buffer
+ (progn
+ (set-visited-file-name old-buffer-name)
+ (set-buffer-modified-p nil))
(kill-buffer (current-buffer))))))
;;;###autoload
(put 'mime-display 'custom-loads '(flow-fill mm-decode mm-view))
(put 'holidays 'custom-loads '(calendar))
-(put 'SQL 'custom-loads '(sql))
(put 'spam-stat 'custom-loads '(spam-stat))
+(put 'SQL 'custom-loads '(sql))
(put 'paren-showing-faces 'custom-loads '(paren))
(put 'refbib 'custom-loads '(refbib))
(put 'elp 'custom-loads '(elp))
(put 'nnmail 'custom-loads '(nnmail))
(put 'chistory 'custom-loads '(chistory))
(put 'shell-directories 'custom-loads '(shell))
-(put 'idlwave-documentation 'custom-loads '(idlwave))
(put 'footnote 'custom-loads '(footnote))
+(put 'idlwave-documentation 'custom-loads '(idlwave))
(put 'pcomplete 'custom-loads '(em-cmpl pcmpl-cvs pcmpl-gnu pcmpl-linux pcmpl-rpm pcomplete))
(put 'gnus-fun 'custom-loads '(gnus-fun))
(put 'org-time 'custom-loads '(org))
(put 'calendar-tex 'custom-loads '(cal-tex))
(put 'savehist 'custom-loads '(savehist))
(put 'mail-hist 'custom-loads '(mail-hist))
+(put 'org-publish 'custom-loads '(org-publish))
(put 'gnus-article-emphasis 'custom-loads '(gnus-art))
(put 'dunnet 'custom-loads '(dunnet))
(put 'fortran 'custom-loads '(fortran))
(put 'woman-faces 'custom-loads '(woman))
(put 'ps-print-vertical 'custom-loads '(ps-print))
(put 'supercite-hooks 'custom-loads '(supercite))
-(put 'vhdl-menu 'custom-loads '(vhdl-mode))
-(put 'chinese-calendar 'custom-loads '(cal-china))
(put 'gnus-newsrc 'custom-loads '(gnus-start))
(put 'erc-replace 'custom-loads '(erc-replace))
+(put 'chinese-calendar 'custom-loads '(cal-china))
+(put 'vhdl-menu 'custom-loads '(vhdl-mode))
(put 'edt 'custom-loads '(edt))
(put 'expand 'custom-loads '(expand))
(put 'erc-paranoia 'custom-loads '(erc))
(put 'dabbrev 'custom-loads '(dabbrev))
(put 'completion 'custom-loads '(completion iswitchb))
(put 'cpp 'custom-loads '(cpp))
-(put 'dig 'custom-loads '(dig net-utils))
+(put 'dig 'custom-loads '(dig))
(put 'ps-print-background 'custom-loads '(ps-print))
(put 'dns-mode 'custom-loads '(dns-mode))
-(put 'org-archive 'custom-loads '(org))
(put 'gnus-score-expire 'custom-loads '(gnus-kill gnus-score))
+(put 'org-archive 'custom-loads '(org))
(put 'tramp 'custom-loads '(tramp tramp-ftp tramp-smb))
(put 'supercite-frames 'custom-loads '(supercite))
(put 'dirtrack 'custom-loads '(dirtrack))
(put 'gnus-summary-maneuvering 'custom-loads '(gnus-sum))
(put 'gnus-start 'custom-loads '(gnus-start gnus gnus-group gnus-int gnus-util nnheader))
(put 'dcl 'custom-loads '(dcl-mode))
-(put 'ogonek 'custom-loads '(ogonek))
(put 'gnus-extract-view 'custom-loads '(gnus-sum gnus-uu))
+(put 'ogonek 'custom-loads '(ogonek))
(put 'dired-keys 'custom-loads '(dired-x))
(put 'lisp-mnt 'custom-loads '(lisp-mnt))
(put 'ediff-mult 'custom-loads '(ediff-mult))
(put 'gnus-meta 'custom-loads '(gnus))
(put 'mouse-sel 'custom-loads '(mouse-sel))
(put 'sort 'custom-loads '(sort))
-(put 'antlr 'custom-loads '(antlr-mode))
(put 'mail-source 'custom-loads '(mail-source nndiary pop3))
+(put 'antlr 'custom-loads '(antlr-mode))
(put 'trace 'custom-loads '(trace))
(put 'gnus-article-washing 'custom-loads '(gnus-art))
(put 'org-agenda-daily/weekly 'custom-loads '(org))
(put 'yow 'custom-loads '(yow))
(put 'reftex-defining-label-environments 'custom-loads '(reftex-vars))
-(put 'asm 'custom-loads '(asm-mode))
(put 'gnus-score-files 'custom-loads '(gnus-score gnus))
+(put 'asm 'custom-loads '(asm-mode))
(put 'mail-abbrev 'custom-loads '(mailabbrev))
(put 'grep 'custom-loads '(grep))
-(put 'feedmail 'custom-loads '(feedmail))
(put 'gnus-agent 'custom-loads '(gnus gnus-agent))
+(put 'feedmail 'custom-loads '(feedmail))
(put 'message-news 'custom-loads '(message))
(put 'smime 'custom-loads '(smime))
(put 'eshell 'custom-loads '(esh-arg eshell esh-cmd esh-ext esh-io esh-mode esh-module esh-opt esh-proc esh-test esh-util esh-var))
(put 'jka-compr 'custom-loads '(jka-compr))
(put 'development 'custom-loads '(cus-edit))
(put 'ediff 'custom-loads '(ediff-init ediff-diff ediff-mult ediff-ptch ediff ediff-wind))
-(put 'feedmail-spray 'custom-loads '(feedmail))
(put 'spam 'custom-loads '(spam))
+(put 'feedmail-spray 'custom-loads '(feedmail))
(put 'allout-encryption 'custom-loads '(allout))
(put 'org-sparse-trees 'custom-loads '(org))
(put 'idlwave-external-programs 'custom-loads '(idlwave))
(put 'smiley 'custom-loads '(smiley))
(put 'extensions 'custom-loads '(cust-print eldoc ido page-ext sha1 time-stamp wid-edit))
(put 'tetris 'custom-loads '(tetris))
-(put 'ebnf-displacement 'custom-loads '(ebnf2ps))
(put 'appt 'custom-loads '(appt))
+(put 'ebnf-displacement 'custom-loads '(ebnf2ps))
(put 'url-history 'custom-loads '(url-history))
(put 'erc-netsplit 'custom-loads '(erc-netsplit))
(put 'snmp 'custom-loads '(snmp-mode))
(put 'widget-documentation 'custom-loads '(wid-edit))
(put 'ld-script 'custom-loads '(ld-script))
(put 'eshell-banner 'custom-loads '(em-banner))
-(put 'artist 'custom-loads '(artist))
(put 'gnus-score-various 'custom-loads '(gnus gnus-score))
+(put 'artist 'custom-loads '(artist))
(put 'cperl-faces 'custom-loads '(cperl-mode))
(put 'goto-address 'custom-loads '(goto-addr))
(put 'inferior-lisp 'custom-loads '(inf-lisp))
(put 'lazy-highlight 'custom-loads '(ispell))
(put 'tpu 'custom-loads '("tpu-extras" tpu-edt))
(put 'w32 'custom-loads '("w32-vars"))
-(put 'viper-hooks 'custom-loads '(viper-init))
(put 'gnus-cite 'custom-loads '(gnus-cite))
+(put 'viper-hooks 'custom-loads '(viper-init))
(put 'gnus-demon 'custom-loads '(gnus-demon))
(put 'newsticker 'custom-loads '(newsticker))
(put 'reftex-optimizations-for-large-documents 'custom-loads '(reftex-vars))
(put 'org-export-translation 'custom-loads '(org))
(put 'file-cache 'custom-loads '(filecache))
(put 'uce 'custom-loads '(uce))
-(put 'org-tags 'custom-loads '(org))
(put 'starttls 'custom-loads '(starttls))
+(put 'org-tags 'custom-loads '(org))
(put 'org-remember 'custom-loads '(org))
(put 'org-export-html 'custom-loads '(org))
(put 'matching 'custom-loads '(bookmark completion ffap imenu))
+(put 'org-mouse 'custom-loads '(org-mouse))
(put 'custom-faces 'custom-loads '(cus-edit))
(put 'smtpmail 'custom-loads '(smtpmail))
(put 'lisp-indent 'custom-loads '("cl-indent"))
(put 'midnight 'custom-loads '(midnight))
(put 'tex 'custom-loads '(bibtex tex-mode reftex-vars))
-(put 'cperl-indentation-details 'custom-loads '(cperl-mode))
(put 'mail-extr 'custom-loads '(mail-extr))
+(put 'cperl-indentation-details 'custom-loads '(cperl-mode))
(put 'filesets 'custom-loads '(filesets))
(put 'double 'custom-loads '(double))
(put 'allout-developer 'custom-loads '(allout))
(put 'tcl 'custom-loads '(tcl))
(put 'vhdl-print 'custom-loads '(vhdl-mode))
(put 'url-mime 'custom-loads '(url-vars))
-(put 'artist-text 'custom-loads '(artist))
(put 'gnus-summary-tree 'custom-loads '(gnus-salt))
+(put 'artist-text 'custom-loads '(artist))
(put 'tar 'custom-loads '(tar-mode))
(put 'url-hairy 'custom-loads '(url-vars url-util))
(put 'archive 'custom-loads '(arc-mode))
(put 'org-startup 'custom-loads '(org))
(put 'testcover 'custom-loads '(testcover))
(put 'gnus-score-default 'custom-loads '(gnus-sum gnus-score))
-(put 'ebnf-except 'custom-loads '(ebnf2ps))
(put 'nnmail-duplicate 'custom-loads '(nnmail))
+(put 'ebnf-except 'custom-loads '(ebnf2ps))
(put 'handwrite 'custom-loads '(handwrite))
(put 'ses 'custom-loads '(ses))
(put 'eshell-proc 'custom-loads '(esh-proc))
(put 'partial-completion 'custom-loads '(complete))
(put 'whitespace 'custom-loads '(whitespace))
(put 'maint 'custom-loads '(emacsbug gulp lisp-mnt))
-(put 'pages 'custom-loads '(page-ext))
(put 'message-interface 'custom-loads '(message))
+(put 'pages 'custom-loads '(page-ext))
(put 'diary 'custom-loads '(calendar diary-lib solar))
(put 'custom-magic-faces 'custom-loads '(cus-edit))
(put 'emacsbug 'custom-loads '(emacsbug))
(put 'tex-view 'custom-loads '(tex-mode))
+(put 'org-agenda-line-format 'custom-loads '(org))
(put 'nnmail-files 'custom-loads '(nnmail))
(put 'gnus-edit-form 'custom-loads '(gnus-eform))
-(put 'org-keywords 'custom-loads '(org))
(put 'gnus-audio 'custom-loads '(gnus-audio))
+(put 'org-keywords 'custom-loads '(org))
(put 'modula2 'custom-loads '(modula2))
(put 'ps-print-color 'custom-loads '(ps-print))
(put 'gnus-diary 'custom-loads '(gnus-diary nndiary))
(put 'abbrev 'custom-loads '(cus-edit dabbrev expand hippie-exp quickurl))
(put 'ediff-merge 'custom-loads '(ediff-init ediff-merg))
(put 'reveal 'custom-loads '(reveal))
-(put 'vhdl 'custom-loads '(vhdl-mode))
(put 'gnus-summary-mail 'custom-loads '(gnus-sum))
+(put 'vhdl 'custom-loads '(vhdl-mode))
(put 'ebnf-optimization 'custom-loads '(ebnf2ps))
(put 'apropos 'custom-loads '(apropos))
(put 'gomoku 'custom-loads '(gomoku))
(put 'pcmpl-gnu 'custom-loads '(pcmpl-gnu))
(put 'org-export-tables 'custom-loads '(org))
(put 'ps-print-face 'custom-loads '(ps-print))
-(put 'org-reveal-location 'custom-loads '(org))
(put 'rmail-summary 'custom-loads '(rmail rmailsum))
(put 'metamail 'custom-loads '(metamail))
(put 'winner 'custom-loads '(winner))
-(put 'org-agenda-prefix 'custom-loads '(org))
(put 'ebrowse-faces 'custom-loads '(ebrowse))
(put 'org-agenda-skip 'custom-loads '(org))
(put 'org-font-lock 'custom-loads '(org))
(put 'pc-select 'custom-loads '(pc-select))
(put 'vera 'custom-loads '(vera-mode))
(put 'i18n 'custom-loads '(ccl double iso-ascii latin1-disp cus-edit ogonek url-vars))
-(put 'org 'custom-loads '(org))
+(put 'org 'custom-loads '(org org-mouse org-publish))
(put 'sh 'custom-loads '(sh-script))
(put 'message-headers 'custom-loads '(message))
(put 'idlwave-code-formatting 'custom-loads '(idlwave))
(put 'basic-faces 'custom-loads '(cus-edit shadowfile))
-(put 'net-utils 'custom-loads '(net-utils))
+(put 'net-utils 'custom-loads '(net-utils dig))
(put 'vhdl-naming 'custom-loads '(vhdl-mode))
(put 'columns 'custom-loads '(delim-col))
(put 'pp 'custom-loads '(pp))
(put 'environment 'custom-loads '(cus-edit dired "dos-vars" "w32-vars"))
(put 'perl 'custom-loads '(perl-mode))
(put 'erc-server 'custom-loads '(erc-backend))
-(put 'vhdl-port 'custom-loads '(vhdl-mode))
(put 'gnus-charset 'custom-loads '(gnus gnus-group gnus-sum))
+(put 'vhdl-port 'custom-loads '(vhdl-mode))
(put 'calculator 'custom-loads '(calculator))
(put 'conf 'custom-loads '(conf-mode))
(put 'custom-menu 'custom-loads '(cus-edit))
(put 'mime-security 'custom-loads '(gnus-art mm-decode mml2015))
(put 'PostScript 'custom-loads '(ps-mode))
(put 'abbrev-mode 'custom-loads '(cus-edit mailabbrev))
-(put 'eshell-term 'custom-loads '(em-term))
(put 'earcon 'custom-loads '(earcon))
+(put 'eshell-term 'custom-loads '(em-term))
(put 'feedmail-headers 'custom-loads '(feedmail))
(put 'newsticker-faces 'custom-loads '(newsticker))
(put 'hypermedia 'custom-loads '(browse-url goto-addr metamail org url-vars wid-edit))
(put 'mm-url 'custom-loads '(mm-url))
(put 'pcl-cvs 'custom-loads '(pcvs-defs pcvs-info pcvs pcvs-parse cvs-status log-edit log-view))
(put 'rmail-files 'custom-loads '(rmail))
+(put 'org-agenda-export 'custom-loads '(org))
(put 'gnus-summary-format 'custom-loads '(gnus-diary gnus gnus-sum))
(put 'windmove 'custom-loads '(windmove))
(put 'terminals 'custom-loads '(terminal))
(put 'gnus-soup 'custom-loads '(gnus-soup))
(put 'table-hooks 'custom-loads '(table))
(put 'sh-indentation 'custom-loads '(sh-script))
-(put 'ebnf-production 'custom-loads '(ebnf2ps))
(put 'gnus-files 'custom-loads '(gnus nnmail))
+(put 'ebnf-production 'custom-loads '(ebnf2ps))
(put 'gnus-windows 'custom-loads '(gnus-win))
-(put 'reftex-label-support 'custom-loads '(reftex-vars))
(put 'gnus-article-buttons 'custom-loads '(gnus-art))
+(put 'reftex-label-support 'custom-loads '(reftex-vars))
(put 'gnus-summary 'custom-loads '(gnus-sum gnus))
(put 'compilation 'custom-loads '(compile))
(put 'erc-ezbounce 'custom-loads '(erc-ezbounce))
(put 'gnus-group 'custom-loads '(gnus gnus-group gnus-topic))
(put 'ediff-vers 'custom-loads '(ediff-vers))
(put 'eudc-bbdb 'custom-loads '(eudc-vars))
-(put 'reftex-referencing-labels 'custom-loads '(reftex-vars))
(put 'gnus-article-various 'custom-loads '(gnus-art gnus-sum))
+(put 'reftex-referencing-labels 'custom-loads '(reftex-vars))
(put 'imap 'custom-loads '(imap))
(put 'ediff-diff 'custom-loads '(ediff-diff))
(put 'ebnf-repeat 'custom-loads '(ebnf2ps))
(put 'octave 'custom-loads '(octave-mod octave-inf))
(put 'editing-basics 'custom-loads '(cua-base pc-select))
(put 'kmacro 'custom-loads '(kmacro))
-(put 'fortune-signature 'custom-loads '(fortune))
(put 'newsticker-layout 'custom-loads '(newsticker))
+(put 'fortune-signature 'custom-loads '(fortune))
(put 'nnmail-expire 'custom-loads '(nnmail))
(put 'gnus-article-saving 'custom-loads '(gnus gnus-art))
(put 'icomplete 'custom-loads '(icomplete))
(put 'outlines 'custom-loads '(allout org outline))
(put 'latin1-display 'custom-loads '(latin1-disp))
(put 'paragraphs 'custom-loads '(table))
+(put 'nnmail-split 'custom-loads '(nndiary nnmail))
(put 'vhdl-model 'custom-loads '(vhdl-mode))
(put 'ebrowse 'custom-loads '(ebrowse))
-(put 'nnmail-split 'custom-loads '(nndiary nnmail))
(put 'makefile 'custom-loads '(make-mode))
(put 'supercite-attr 'custom-loads '(supercite))
(put 'org-export-general 'custom-loads '(org))
(put 'gnus-server-visual 'custom-loads '(gnus-srvr))
(put 'fortune 'custom-loads '(fortune))
+(put 'org-export-latex 'custom-loads '(org-export-latex org))
(put 'whitespace-faces 'custom-loads '(whitespace))
(put 'diff-mode 'custom-loads '(diff-mode))
(put 'gnus-asynchronous 'custom-loads '(gnus-async))
(put 'ps-print-font 'custom-loads '(ps-print ps-mule))
(put 'eshell-basic 'custom-loads '(em-basic))
(put 'vhdl-misc 'custom-loads '(vhdl-mode))
-(put 'rmail-obsolete 'custom-loads '(rmail))
(put 'nntp 'custom-loads '(nntp))
+(put 'rmail-obsolete 'custom-loads '(rmail))
(put 'dired-x 'custom-loads '(dired-x))
(put 'spook 'custom-loads '(spook))
(put 'tex-file 'custom-loads '(tex-mode))
(put 'time-stamp 'custom-loads '(time-stamp))
(put 'todo 'custom-loads '(todo-mode))
(put 'rmail-spam-filter 'custom-loads '(rmail-spam-filter))
+(put 'gnus-article-highlight 'custom-loads '(gnus-art))
(put 'org-edit-structure 'custom-loads '(org))
(put 'ebnf-special 'custom-loads '(ebnf2ps))
-(put 'gnus-article-highlight 'custom-loads '(gnus-art))
(put 'isearchb 'custom-loads '(isearchb))
(put 'ido 'custom-loads '(ido))
(put 'tooltip 'custom-loads '(gud))
(put 'edebug 'custom-loads '(edebug))
(put 'org-agenda-custom-commands 'custom-loads '(org))
(put 'emerge 'custom-loads '(emerge))
+(put 'org-properties 'custom-loads '(org))
(put 'scheme 'custom-loads '(cmuscheme scheme))
(put 'spam-report 'custom-loads '(spam-report))
(put 'org-cycle 'custom-loads '(org))
-(put 'gametree 'custom-loads '(gametree))
-(put 'newsticker-hooks 'custom-loads '(newsticker))
(put 'gmm 'custom-loads '(gmm-utils))
+(put 'newsticker-hooks 'custom-loads '(newsticker))
+(put 'gametree 'custom-loads '(gametree))
(put 'gnus-group-foreign 'custom-loads '(gnus-msg gnus-group))
-(put 'org-plain-lists 'custom-loads '(org))
+(put 'org-plain-lists 'custom-loads '(org org-export-latex))
(put 'pgg-pgp5 'custom-loads '(pgg-pgp5))
(put 'erc-spelling 'custom-loads '(erc-spelling))
(put 'sh-script 'custom-loads '(sh-script))
(put 'cperl-speed 'custom-loads '(cperl-mode))
(put 'PostScript-edit 'custom-loads '(ps-mode))
(put 'calendar 'custom-loads '(calendar cal-dst cal-html solar icalendar midnight org todo-mode))
-(put 'rcirc-faces 'custom-loads '(rcirc))
+(put 'org-imenu-and-speedbar 'custom-loads '(org))
(put 'spam-ifile 'custom-loads '(spam))
+(put 'rcirc-faces 'custom-loads '(rcirc))
(put 'programming 'custom-loads '(cus-edit))
(put 'meta-font 'custom-loads '(meta-mode))
(put 'ps-print-zebra 'custom-loads '(ps-print))
(put 'sendmail 'custom-loads '(sendmail))
(put 'gnus-article-signature 'custom-loads '(gnus-art))
(put 'eshell-ls 'custom-loads '(em-ls))
-(put 'idlwave 'custom-loads '(idlwave idlw-help idlw-shell))
(put 'erc-speedbar 'custom-loads '(erc-speedbar))
+(put 'idlwave 'custom-loads '(idlwave idlw-help idlw-shell))
(put 'thumbs 'custom-loads '(thumbs))
(put 'newsticker-headline-processing 'custom-loads '(newsticker))
(put 'erc-sound 'custom-loads '(erc-sound))
(put 'erc-truncate 'custom-loads '(erc-truncate))
-(put 'viper-ex 'custom-loads '(viper-ex))
(put 'gulp 'custom-loads '(gulp))
+(put 'viper-ex 'custom-loads '(viper-ex))
(put 'leim 'custom-loads '(quail))
(put 'ielm 'custom-loads '(ielm))
(put 'erc 'custom-loads '(erc-autoaway erc-join erc erc-button erc-capab erc-goodies erc-dcc erc-ezbounce erc-fill erc-hecomplete erc-ibuffer erc-identd erc-log erc-match erc-netsplit erc-networks erc-notify erc-page erc-pcomplete erc-replace erc-services erc-sound erc-speedbar erc-stamp erc-track erc-truncate))
(custom-put-if-not 'mime-display 'custom-version "21.1")
(custom-put-if-not 'mime-display 'group-documentation "Display of MIME in mail and news articles.")
-(custom-put-if-not 'SQL 'custom-version "20.4")
-(custom-put-if-not 'SQL 'group-documentation "Running a SQL interpreter from within Emacs buffers.")
(custom-put-if-not 'spam-stat 'custom-version "22.1")
(custom-put-if-not 'spam-stat 'group-documentation "Statistical spam detection for Emacs.
Use the functions to build a dictionary of words and their statistical
distribution in spam and non-spam mails. Then use a function to determine
whether a buffer contains spam or not.")
+(custom-put-if-not 'SQL 'custom-version "20.4")
+(custom-put-if-not 'SQL 'group-documentation "Running a SQL interpreter from within Emacs buffers.")
(custom-put-if-not 'paren-showing-faces 'custom-version "22.1")
(custom-put-if-not 'paren-showing-faces 'group-documentation "Group for faces of Show Paren mode.")
(custom-put-if-not 'iimage 'custom-version "22.1")
(custom-put-if-not 'quickurl 'group-documentation "Insert an URL based on text at point in buffer.")
(custom-put-if-not 'comment 'custom-version "21.1")
(custom-put-if-not 'comment 'group-documentation "Indenting and filling of comments.")
-(custom-put-if-not 'gametree 'custom-version "20.3")
-(custom-put-if-not 'gametree 'group-documentation "Manage game analysis trees in Emacs.")
(custom-put-if-not 'gmm 'custom-version "22.1")
(custom-put-if-not 'gmm 'group-documentation "Utility functions for Gnus, Message and MML")
+(custom-put-if-not 'gametree 'custom-version "20.3")
+(custom-put-if-not 'gametree 'group-documentation "Manage game analysis trees in Emacs.")
(custom-put-if-not 'ps-print-zebra 'custom-version "20")
(custom-put-if-not 'ps-print-zebra 'group-documentation "Zebra customization.")
(custom-put-if-not 'ps-print-zebra 'custom-tag "Zebra")
(custom-put-if-not 'delphi 'custom-version "21.1")
(custom-put-if-not 'delphi 'group-documentation "Major mode for editing Delphi source in Emacs.")
-(defvar custom-versions-load-alist '(("21.2" mm-util) ("20.3.3" "dos-vars") ("20.1" time-stamp) ("21.3" sql gnus-agent ange-ftp) ("19.29" time-stamp) ("22" ebnf2ps) ("22.2" vc-hg bibtex-style vc-mtn gnus-sum css-mode desktop tls mail-source find-dired gdb-ui dired) ("20.3" easymenu dabbrev ffap xscheme rmail paren mailabbrev uce which-func diary-lib sendmail debug msb avoid hexl vcursor vc compile etags browse-url add-log find-func cus-edit) ("21.1" server debug rmailedit ezimage dabbrev latin1-disp gnus-start hideshow strokes sgml-mode net-utils cperl-mode ange-ftp gnus-nocem paren fortran solar etags rmail sb-image vc-sccs vc gnus-group gnus-sum smtpmail add-log sendmail find-func wid-edit vc-rcs gnus-art nnmail message ps-print vc-cvs cus-edit gnus-agent flyspell rmailsum browse-url) ("20.4" crisp sh-script compile hilit-chg) ("20" ps-print ebnf2ps) ("20.8" sql) ("22.1" imenu mm-view cal-tex gnus-srvr gnus-score smiley add-log bookmark footnote shadowfile gnus-int view hi-lock gnus-win server tcl descr-text latin1-disp fortran landmark gnus-delay tex-mode sgml-mode gnus-group sql gnus-util mail-extr sh-script hl-line make-mode mml2015 vc-cvs ielm nnimap generic-x imap gnus-soup gnus-start mml-sec comint vc-mcvs desktop locate gnus-msg compare-w info uudecode gnus-agent cal-dst spam find-dired diff-mode ange-ftp mml gnus-fun ispell gnus-spec gnus warnings smtpmail sendmail appt dabbrev pop3 smime time binhex dired rmail allout mm-url gdb-ui vc-svn mm-decode mm-util vc pgg-def mm-uu autorevert mail-source flow-fill diary-lib iswitchb gnus-art find-func gnus-cite tls nnmail glasses deuglify calendar ffap compile starttls cus-edit gnus-sum grep keypad message))
+(defvar custom-versions-load-alist '(("22.3" message) ("21.2" mm-util) ("20.3.3" "dos-vars") ("20.1" time-stamp) ("21.3" sql gnus-agent ange-ftp) ("19.29" time-stamp) ("22" ebnf2ps) ("22.2" vc-hg bibtex-style vc-mtn gnus-sum css-mode desktop tls mail-source find-dired gdb-ui dired) ("20.3" easymenu dabbrev ffap xscheme rmail paren mailabbrev uce which-func diary-lib sendmail debug msb avoid hexl vcursor vc compile etags browse-url add-log find-func cus-edit) ("21.1" server debug rmailedit ezimage dabbrev latin1-disp gnus-start hideshow strokes sgml-mode net-utils cperl-mode ange-ftp gnus-nocem paren fortran solar etags rmail sb-image vc-sccs vc gnus-group gnus-sum smtpmail add-log sendmail find-func wid-edit vc-rcs gnus-art nnmail message ps-print vc-cvs cus-edit gnus-agent flyspell rmailsum browse-url) ("20.4" crisp sh-script compile hilit-chg) ("20" ps-print ebnf2ps) ("20.8" sql) ("22.1" imenu mm-view cal-tex gnus-srvr gnus-score smiley add-log bookmark footnote shadowfile gnus-int view hi-lock gnus-win server tcl descr-text latin1-disp fortran landmark gnus-delay tex-mode sgml-mode gnus-group sql gnus-util mail-extr sh-script hl-line make-mode mml2015 vc-cvs ielm nnimap generic-x imap gnus-soup gnus-start mml-sec comint vc-mcvs desktop locate gnus-msg compare-w info uudecode cal-dst gnus-agent spam find-dired diff-mode ange-ftp mml gnus-fun ispell gnus-spec warnings gnus smtpmail sendmail appt dabbrev pop3 smime time binhex dired rmail allout mm-url gdb-ui vc-svn mm-decode mm-util vc pgg-def mm-uu autorevert mail-source flow-fill diary-lib iswitchb find-func gnus-art gnus-cite tls glasses nnmail deuglify calendar ffap compile starttls cus-edit grep gnus-sum keypad message))
"For internal use by custom.")
(provide 'cus-load)
(const :tag "always" t)))
;; fileio.c
(insert-default-directory minibuffer boolean)
+ (auto-save-visited-file-name auto-save boolean)
(read-file-name-completion-ignore-case minibuffer boolean "22.1")
;; fns.c
(use-dialog-box menu boolean "21.1")
(defcustom desktop-minor-mode-table
'((auto-fill-function auto-fill-mode)
(vc-mode nil)
- (vc-dired-mode nil))
+ (vc-dired-mode nil)
+ (savehist-mode nil))
"Table mapping minor mode variables to minor mode functions.
Each entry has the form (NAME RESTORE-FUNCTION).
NAME is the name of the buffer-local variable indicating that the minor
(replace-match "" t t)))))))
(defconst diff-hunk-header-re-unified
- "^@@ -\\([0-9]+\\),\\([0-9]+\\) \\+\\([0-9]+\\),\\([0-9]+\\) @@")
+ "^@@ -\\([0-9]+\\)\\(?:,\\([0-9]+\\)\\)? \\+\\([0-9]+\\)\\(?:,\\([0-9]+\\)\\)? @@")
(defvar diff-font-lock-keywords
`((,(concat "\\(" diff-hunk-header-re-unified "\\)\\(.*\\)$")
(setq style (cdr (assq (char-after) '((?@ . unified) (?* . context))))))
(goto-char (match-end 0))
(when (and (not donttrustheader) (match-end 2))
- (let* ((nold (string-to-number (match-string 2)))
- (nnew (string-to-number (match-string 4)))
+ (let* ((nold (string-to-number (or (match-string 2) "1")))
+ (nnew (string-to-number (or (match-string 4) "1")))
(endold
(save-excursion
(re-search-forward (if diff-valid-unified-empty-line
(replace-match "***" t t nil 2))
;; we matched a hunk header
(let ((line1 (match-string 4))
- (lines1 (match-string 5))
+ (lines1 (or (match-string 5) "1"))
(line2 (match-string 6))
- (lines2 (match-string 7)))
+ (lines2 (or (match-string 7) "1")))
(replace-match
(concat "***************\n*** " line1 ","
(number-to-string (+ (string-to-number line1)
(old2 (match-string 4))
(new1 (number-to-string (+ space minus)))
(new2 (number-to-string (+ space plus))))
- (unless (string= new2 old2) (replace-match new2 t t nil 4))
- (unless (string= new1 old1) (replace-match new1 t t nil 2))))
+ (if old2
+ (unless (string= new2 old2) (replace-match new2 t t nil 4))
+ (goto-char (match-end 4)) (insert "," new2))
+ (if old1
+ (unless (string= new1 old1) (replace-match new1 t t nil 2))
+ (goto-char (match-end 2)) (insert "," new1))))
((looking-at "--- \\([0-9]+\\),\\([0-9]*\\) ----$")
(when (> (+ space bang plus) 0)
(let* ((old1 (match-string 1))
((eq (char-after) ?@)
(if (not (looking-at diff-hunk-header-re-unified))
(error "Unrecognized unified diff hunk header format")
- (let ((before (string-to-number (match-string 2)))
- (after (string-to-number (match-string 4))))
+ (let ((before (string-to-number (or (match-string 2) "1")))
+ (after (string-to-number (or (match-string 4) "1"))))
(forward-line)
(while
(case (char-after)
(other :tag "ask" t))
:group 'dired)
+;; This is a fluid var used in dired-handle-overwrite. It should be
+;; let-bound whenever dired-copy-file etc are called. See
+;; dired-create-files for an example.
(defvar dired-overwrite-confirmed)
(defun dired-handle-overwrite (to)
(if (file-exists-p to)
(or top (dired-handle-overwrite to))
(condition-case err
- (progn
- (make-directory to)
- (set-file-modes to #o700))
+ ;; We used to call set-file-modes here, but on some
+ ;; Linux kernels, that returns an error on vfat
+ ;; filesystems
+ (let ((default-mode (default-file-modes)))
+ (unwind-protect
+ (progn
+ (set-default-file-modes #o700)
+ (make-directory to))
+ (set-default-file-modes default-mode)))
(file-error
(push (dired-make-relative from)
dired-create-files-failures)
and the rest will be added temporarily to the history and can be retrieved
with \\[previous-history-element] (M-p) .
+The variable `dired-guess-shell-case-fold-search' controls whether
+REGEXP is matched case-sensitively.
+
You can set this variable in your ~/.emacs. For example, to add rules for
`.foo' and `.bar' files, write
(defun dired-dnd-popup-notice ()
(message-box
- "Recursive copies not enabled.\nSee variable dired-recursive-copies."))
+ "Dired recursive copies are currently disabled.\nSee the variable `dired-recursive-copies'."))
(defun dired-dnd-do-ask-action (uri)
Ask means pop up a menu for the user to select one of copy, move or link."
(require 'dired-aux)
(let* ((from (dnd-get-local-file-name uri t))
- (to (if from (concat (dired-current-directory)
- (file-name-nondirectory from))
- nil)))
- (if from
- (cond ((or (eq action 'copy)
- (eq action 'private)) ; Treat private as copy.
-
- ;; If copying a directory and dired-recursive-copies is nil,
- ;; dired-copy-file silently fails. Pop up a notice.
- (if (and (file-directory-p from)
- (not dired-recursive-copies))
- (dired-dnd-popup-notice)
- (progn
- (dired-copy-file from to 1)
- (dired-relist-entry to)
- action)))
-
- ((eq action 'move)
- (dired-rename-file from to 1)
- (dired-relist-entry to)
- action)
-
- ((eq action 'link)
- (make-symbolic-link from to 1)
- (dired-relist-entry to)
- action)
-
- ((eq action 'ask)
- (dired-dnd-do-ask-action uri))
-
- (t nil)))))
+ (to (when from
+ (concat (dired-current-directory)
+ (file-name-nondirectory from)))))
+ (when from
+ (cond ((eq action 'ask)
+ (dired-dnd-do-ask-action uri))
+ ;; If copying a directory and dired-recursive-copies is
+ ;; nil, dired-copy-file fails. Pop up a notice.
+ ((and (memq action '(copy private))
+ (file-directory-p from)
+ (not dired-recursive-copies))
+ (dired-dnd-popup-notice))
+ ((memq action '(copy private move link))
+ (let ((overwrite (and (file-exists-p to)
+ (y-or-n-p
+ (format "Overwrite existing file `%s'? " to))))
+ ;; Binding dired-overwrite-confirmed to nil makes
+ ;; dired-handle-overwrite a no-op. We instead use
+ ;; y-or-n-p, which pops a graphical menu.
+ dired-overwrite-confirmed backup-file)
+ (when (and overwrite
+ ;; d-b-o is defined in dired-aux.
+ (boundp 'dired-backup-overwrite)
+ dired-backup-overwrite
+ (setq backup-file
+ (car (find-backup-file-name to)))
+ (or (eq dired-backup-overwrite 'always)
+ (y-or-n-p
+ (format
+ "Make backup for existing file `%s'? " to))))
+ (rename-file to backup-file 0)
+ (dired-relist-entry backup-file))
+ (cond ((memq action '(copy private))
+ (dired-copy-file from to overwrite))
+ ((eq action 'move)
+ (dired-rename-file from to overwrite))
+ ((eq action 'link)
+ (make-symbolic-link from to overwrite)))
+ (dired-relist-entry to)
+ action))))))
(defun dired-dnd-handle-file (uri action)
"Copy, move or link a file to the dired directory if it is a local file.
(substring name 0 (match-beginning 0))
name)))
(print-length nil)
+ (print-level nil)
(print-readably t) ; This does something in Lucid Emacs.
(float-output-format nil)
(done-any nil)
(defun byte-compile-file (filename &optional load)
"Compile a file of Lisp code named FILENAME into a file of byte code.
The output file's name is generated by passing FILENAME to the
-`byte-compile-dest-file' function (which see).
+function `byte-compile-dest-file' (which see).
With prefix arg (noninteractively: 2nd arg), LOAD the file after compiling.
The value is non-nil if there were no errors, nil if errors."
;; (interactive "fByte compile file: \nP")
(defmacro byte-compile-maybe-guarded (condition &rest body)
"Execute forms in BODY, potentially guarded by CONDITION.
CONDITION is a variable whose value is a test in an `if' or `cond'.
-BODY is the code to compile first arm of the if or the body of the
-cond clause. If CONDITION's value is of the form (fboundp 'foo)
+BODY is the code to compile in the first arm of the if or the body of
+the cond clause. If CONDITION's value is of the form (fboundp 'foo)
or (boundp 'foo), the relevant warnings from BODY about foo's
being undefined will be suppressed.
(defun edebug-gensym (&optional prefix)
"Generate a fresh uninterned symbol.
-There is an optional argument, PREFIX. PREFIX is the
-string that begins the new name. Most people take just the default,
+There is an optional argument, PREFIX. PREFIX is the string
+that begins the new name. Most people take just the default,
except when debugging needs suggest otherwise."
(if (null prefix)
(setq prefix "G"))
sexp))
(defun edebug-unwrap* (sexp)
- "Return the sexp recursively unwrapped."
+ "Return the SEXP recursively unwrapped."
(let ((new-sexp (edebug-unwrap sexp)))
(while (not (eq sexp new-sexp))
(setq sexp new-sexp
This is the Edebug replacement for the standard `signal'. It should
only be active while Edebug is. It checks `debug-on-error' to see
whether it should call the debugger. When execution is resumed, the
-error is signaled again."
+error is signaled again.
+\n(fn SIGNAL-NAME DATA)"
(if (and (listp debug-on-error) (memq edebug-signal-name debug-on-error))
(edebug 'error (cons edebug-signal-name edebug-signal-data)))
;; If we reach here without another non-local exit, then send signal again.
(defun edebug-restore-status (var status)
"Reset VAR based on STATUS.
-STATUS should be a list you got from `edebug-var-status'."
+STATUS should be a list returned by `edebug-var-status'."
(let ((locus (car status))
(value (cdr status)))
(cond ((bufferp locus)
(defun edebug-top-level-nonstop ()
"Set mode to Go-nonstop, and exit to top-level.
-This is useful for exiting even if unwind-protect code may be executed."
+This is useful for exiting even if `unwind-protect' code may be executed."
(interactive)
(setq edebug-execution-mode 'Go-nonstop)
(top-level))
;; A list of expressions and their evaluations is displayed in *edebug*.
(defun edebug-eval-result-list ()
- "Return a list of evaluations of edebug-eval-list"
+ "Return a list of evaluations of `edebug-eval-list'."
;; Assumes in outside environment.
;; Don't do any edebug things now.
(let ((edebug-execution-mode 'Go-nonstop)
;; with calls in user functions, e.g. (edebug-eval-display)
(defun edebug-eval-display (edebug-eval-result-list)
- "Display expressions and evaluations in EVAL-LIST.
+ "Display expressions and evaluations in EDEBUG-EVAL-RESULT-LIST.
It modifies the context by popping up the eval display."
(if edebug-eval-result-list
(progn
(defun edebug-eval-redisplay ()
"Redisplay eval list in outside environment.
-May only be called from within edebug-recursive-edit."
+May only be called from within `edebug-recursive-edit'."
(edebug-create-eval-buffer)
(edebug-outside-excursion
(edebug-eval-display-list (edebug-eval-result-list))
;; edebug is not dependent on this, yet.
(defun edebug (&optional edebug-arg-mode &rest debugger-args)
- "Replacement for debug.
-If we are running an edebugged function,
-show where we last were. Otherwise call debug normally."
+ "Replacement for `debug'.
+If we are running an edebugged function, show where we last were.
+Otherwise call `debug' normally."
;; (message "entered: %s depth: %s edebug-recursion-depth: %s"
;; edebug-entered (recursion-depth) edebug-recursion-depth) (sit-for 1)
(if (and edebug-entered ; anything active?
(defun edebug-trace (fmt &rest args)
- "Convenience call to edebug-trace-display using edebug-trace-buffer"
+ "Convenience call to `edebug-trace-display' using `edebug-trace-buffer'."
(apply 'edebug-trace-display edebug-trace-buffer fmt args))
\f
(let* ((path (cons (or find-function-source-path load-path)
(find-library-suffixes)))
(def (if (eq (function-called-at-point) 'require)
- (save-excursion
- (backward-up-list)
- (forward-char)
- (backward-sexp -2)
- (thing-at-point 'symbol))
+ ;; `function-called-at-point' may return 'require
+ ;; with `point' anywhere on this line. So wrap the
+ ;; `save-excursion' below in a `condition-case' to
+ ;; avoid reporting a scan-error here.
+ (condition-case nil
+ (save-excursion
+ (backward-up-list)
+ (forward-char)
+ (forward-sexp 2)
+ (thing-at-point 'symbol))
+ (error nil))
(thing-at-point 'symbol))))
(when def
(setq def (and (locate-file-completion def path 'test) def)))
(setq symbol (get symbol 'definition-name)))
(if (string-match "\\`src/\\(.*\\.c\\)\\'" library)
(find-function-C-source symbol (match-string 1 library) type)
- (if (string-match "\\.el\\(c\\)\\'" library)
- (setq library (substring library 0 (match-beginning 1))))
+ (when (string-match "\\.el\\(c\\)\\'" library)
+ (setq library (substring library 0 (match-beginning 1))))
+ ;; Strip extension from .emacs.el to make sure symbol is searched in
+ ;; .emacs too.
+ (when (string-match "\\.emacs\\(.el\\)" library)
+ (setq library (substring library 0 (match-beginning 1))))
(let* ((filename (find-library-name library))
(regexp-symbol (cdr (assq type find-function-regexp-alist))))
(with-current-buffer (find-file-noselect filename)
(fset 'edt-emulation-on (symbol-function 'edt-select-user-global-map)))
(progn
(fset 'edt-emulation-on (symbol-function 'edt-select-default-global-map))
- (edt-select-default-global-map))))
+ (edt-select-default-global-map)))
+ ;; We need to share `global-buffers-menu-map' with the saved global
+ ;; keymap, because `menu-bar-update-buffers' directly changes it.
+ (define-key (current-global-map) [menu-bar buffer]
+ (cons "Buffers" global-buffers-menu-map)))
(defun edt-user-emulation-setup ()
"Setup user custom emulation of DEC's EDT editor."
(set-marker tpu-match-end-mark nil))
(defun tpu-match-beginning nil
- "Returns the location of the last match beginning."
+ "Return the location of the last match beginning."
(marker-position tpu-match-beginning-mark))
(defun tpu-match-end nil
- "Returns the location of the last match end."
+ "Return the location of the last match end."
(marker-position tpu-match-end-mark))
(defun tpu-check-match nil
- "Returns t if point is between tpu-match markers.
+ "Return t if point is between tpu-match markers.
Otherwise sets the tpu-match markers to nil and returns nil."
;; make sure 1- marker is in this buffer
;; 2- point is at or after beginning marker
(message "Mark %d set." num))
(defun tpu-goto-breadcrumb (num)
- "Returns to a breadcrumb set with drop-breadcrumb."
+ "Return to a breadcrumb set with drop-breadcrumb."
(interactive "p")
(cond ((get tpu-breadcrumb-plist num)
(switch-to-buffer (car (get tpu-breadcrumb-plist num)))
tpu-version))
(defun tpu-reset-screen-size (height width)
- "Sets the screen size."
+ "Set the screen size."
(interactive "nnew screen height: \nnnew screen width: ")
(set-frame-height (selected-frame) height)
(set-frame-width (selected-frame) width))
(if tpu-newline-and-indent-p " and indents." "."))))
(defun tpu-spell-check nil
- "Checks the spelling of the region, or of the entire buffer if no
- region is selected."
+ "Check the spelling of the region, or of the entire buffer,
+ if no region is selected."
(interactive)
(cond (tpu-have-ispell
(if (tpu-mark) (ispell-region (tpu-mark) (point)) (ispell-buffer)))
(if (tpu-mark) (tpu-unselect t)))
(defun tpu-toggle-overwrite-mode nil
- "Switches in and out of overwrite mode"
+ "Switch in and out of overwrite mode."
(interactive)
(cond (overwrite-mode
(tpu-local-set-key "\177" tpu-saved-delete-func)
;;; TPU line-mode commands
;;;
(defun tpu-include (file)
- "TPU-like include file"
+ "TPU-like include file."
(interactive "fInclude file: ")
(insert-file-contents file)
(message ""))
(defun tpu-get (file)
- "TPU-like get file"
+ "TPU-like get file."
(interactive "FFile to get: ")
(find-file file find-file-wildcards))
(defun tpu-what-line nil
- "Tells what line the point is on,
+ "Tell what line the point is on,
and the total number of lines in the buffer."
(interactive)
(if (eobp)
;;; Auto-insert
;;;
(defun tpu-insert-escape nil
- "Inserts an escape character, and so becomes the escape-key alias."
+ "Insert an escape character, and so becomes the escape-key alias."
(interactive)
(insert "\e"))
(defun tpu-insert-formfeed nil
- "Inserts a formfeed character."
+ "Insert a formfeed character."
(interactive)
(insert "\C-L"))
(defvar tpu-saved-control-r nil "Saved value of Control-r.")
(defun tpu-end-define-macro-key (key)
- "Ends the current macro definition"
+ "End the current macro definition."
(interactive "kPress the key you want to use to do what was just learned: ")
(end-kbd-macro nil)
(global-set-key key last-kbd-macro)
;;; Buffers and Windows
;;;
(defun tpu-kill-buffer nil
- "Kills the current buffer. If tpu-kill-buffers-silently is non-nil,
-kills modified buffers without asking."
+ "Kill the current buffer.
+If `tpu-kill-buffers-silently' is non-nil,
+kill modified buffers without asking."
(interactive)
(if tpu-kill-buffers-silently (set-buffer-modified-p nil))
(kill-buffer (current-buffer)))
(switch-to-buffer (car (reverse list)))))
(defun tpu-make-file-buffer-list (buffer-list)
- "Returns names from BUFFER-LIST excluding those beginning with a space or star."
+ "Return names from BUFFER-LIST excluding those beginning with a space or star."
(delq nil (mapcar '(lambda (b)
(if (or (= (aref (buffer-name b) 0) ? )
(= (aref (buffer-name b) 0) ?*)) nil b))
;;; Search
;;;
(defun tpu-toggle-regexp nil
- "Switches in and out of regular expression search and replace mode."
+ "Switch in and out of regular expression search and replace mode."
(interactive)
(setq tpu-regexp-p (not tpu-regexp-p))
(tpu-set-search)
(defalias 'tpu-search-internal-core (symbol-function 'tpu-search-internal))
(defun tpu-check-search-case (string)
- "Returns t if string contains upper case."
+ "Return t if string contains upper case."
;; if using regexp, eliminate upper case forms (\B \W \S.)
(if tpu-regexp-p
(let ((pat (copy-sequence string)) (case-fold-search nil) (pos 0))
;;; Select / Unselect
;;;
(defun tpu-select (&optional quiet)
- "Sets the mark to define one end of a region."
+ "Set the mark to define one end of a region."
(interactive "P")
(cond ((tpu-mark)
(tpu-unselect quiet))
(if (not quiet) (message "Move the text cursor to select text.")))))
(defun tpu-unselect (&optional quiet)
- "Removes the mark to unselect the current region."
+ "Remove the mark to unselect the current region."
(interactive "P")
(deactivate-mark)
(setq mark-ring nil)
(tpu-error "No selection active."))))
(defun tpu-cut (arg)
- "Copy selected region to the cut buffer. In the absence of an
-argument, delete the selected region too."
+ "Copy selected region to the cut buffer.
+In the absence of an argument, delete the selected region too."
(interactive "P")
(if arg (tpu-store-text) (tpu-cut-text)))
(defun tpu-append-region (arg)
- "Append selected region to the tpu-cut buffer. In the absence of an
-argument, delete the selected region too."
+ "Append selected region to the tpu-cut buffer.
+In the absence of an argument, delete the selected region too."
(interactive "P")
(cond ((tpu-mark)
(let ((beg (region-beginning)) (end (region-end)))
(delete-region beg (point))))
(defun tpu-delete-current-char (num)
- "Delete one or specified number of characters after point. The last
-character deleted is saved for the TPU-edt undelete-char command."
+ "Delete one or specified number of characters after point.
+The last character deleted is saved for the TPU-edt undelete-char command."
(interactive "p")
(while (and (> num 0) (not (eobp)))
(setq tpu-last-deleted-char (char-after (point)))
(message "Replaced %s occurrence%s." strings (if (not (= 1 strings)) "s" ""))))
(defun tpu-emacs-replace (&optional dont-ask)
- "A TPU-edt interface to the Emacs replace functions. If TPU-edt is
-currently in regular expression mode, the Emacs regular expression
-replace functions are used. If an argument is supplied, replacements
-are performed without asking. Only works in forward direction."
+ "A TPU-edt interface to the Emacs replace functions.
+If TPU-edt is currently in regular expression mode, the Emacs regular
+expression replace functions are used. If an argument is supplied,
+replacements are performed without asking. Only works in forward direction."
(interactive "P")
(cond (dont-ask
(setq current-prefix-arg nil)
(end-of-line) (insert text) (forward-line))))))
(defun tpu-trim-line-ends nil
- "Removes trailing whitespace from every line in the buffer."
+ "Remove trailing whitespace from every line in the buffer."
(interactive)
(save-match-data
(save-excursion
(setq tpu-control-keys tpu-style)))
(defun tpu-toggle-control-keys nil
- "Toggles control key bindings between TPU-edt and Emacs."
+ "Toggle control key bindings between TPU-edt and Emacs."
(interactive)
(tpu-reset-control-keys (not tpu-control-keys))
(and (interactive-p)
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
2008-02-05 Juanma Barranquero <lekktu@gmail.com>
* erc.el (erc-valid-nick-regexp):
"Output a list of FILES.
Each member of FILES is either a string or a cons cell of the form
\(FILE . ATTRS)."
- (if (memq listing-style '(long-listing single-column))
+ ;; Mimic behavior of coreutils ls, which lists a single file per
+ ;; line when output is not a tty. Exceptions: if -x was supplied.
+ ;; Not really the same since not testing output destination.
+ (if (or (and eshell-in-pipeline-p
+ (not (eq listing-style 'by-lines)))
+ (memq listing-style '(long-listing single-column)))
(eshell-for file files
(if file
(eshell-ls-file file size-width copy-fileinfo)))
command that produces no output, and exits successfully.
If set to `not-even-short-output', then the definition of \"quick
-command\" is extended to include commands that produce output, iff
-that output can be presented in its entirely in the Eshell window."
+command\" is extended to include commands that produce output, if and
+only if that output can be presented in its entirely in the Eshell window."
:type '(choice (const :tag "No" nil)
(const :tag "Yes" t)
(const :tag "Not even short output"
(= (+ pos 2) (point-max))))))
(defun eshell-quote-backslash (string &optional index)
- "Intelligently backslash the character occuring in STRING at INDEX.
+ "Intelligently backslash the character occurring in STRING at INDEX.
If the character is itself a backslash, it needs no escaping."
(let ((char (aref string index)))
(if (eq char ?\\)
,(purecopy "^widget-") ,(purecopy "^custom-") ,(purecopy "^vm-"))
"*List of faces that are of no interest to the user.")
(make-obsolete-variable 'facemenu-unlisted-faces 'facemenu-listed-faces
- "since 22.1,\nand has no effect on the Face menu")
+ "22.1,\nand has no effect on the Face menu")
(defcustom facemenu-listed-faces nil
"*List of faces to include in the Face menu.
:type 'boolean
:group 'auto-save)
-(defcustom auto-save-visited-file-name nil
- "Non-nil says auto-save a buffer in the file it is visiting, when practical.
-Normally auto-save files are written under other names."
- :type 'boolean
- :group 'auto-save)
-
(defcustom auto-save-file-name-transforms
`(("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'"
;; Don't put "\\2" inside expand-file-name, since it will be
(file-exists-p (file-name-directory
(substring filename (1- (match-end 0))))))
(setq filename (substring filename (1- (match-end 0)))))
- (let ((tail directory-abbrev-alist))
+ ;; Avoid treating /home/foo as /home/Foo during `~' substitution.
+ ;; To fix this right, we need a `file-name-case-sensitive-p'
+ ;; function, but we don't have that yet, so just guess.
+ (let ((case-fold-search
+ (memq system-type '(ms-dos windows-nt darwin cygwin))))
;; If any elt of directory-abbrev-alist matches this name,
;; abbreviate accordingly.
- (while tail
- (if (string-match (car (car tail)) filename)
+ (dolist (dir-abbrev directory-abbrev-alist)
+ (if (string-match (car dir-abbrev) filename)
(setq filename
- (concat (cdr (car tail)) (substring filename (match-end 0)))))
- (setq tail (cdr tail)))
+ (concat (cdr dir-abbrev)
+ (substring filename (match-end 0))))))
;; Compute and save the abbreviated homedir name.
;; We defer computing this until the first time it's needed, to
;; give time for directory-abbrev-alist to be set properly.
;; Filter for \\[find-dired] processes.
(let ((buf (process-buffer proc))
(inhibit-read-only t))
- (if (buffer-name buf) ; not killed?
- (save-excursion
- (set-buffer buf)
+ (if (buffer-name buf)
+ (with-current-buffer buf
(save-restriction
(widen)
- (save-excursion
- (let ((buffer-read-only nil)
- (end (point-max)))
- (goto-char end)
- (insert string)
- (goto-char end)
- (or (looking-at "^")
- (forward-line 1))
- (while (looking-at "^")
- (insert " ")
+ (let ((buffer-read-only nil)
+ (beg (point-max))
+ (l-opt (and (consp find-ls-option)
+ (string-match "l" (cdr find-ls-option))))
+ (ls-regexp (concat "^ +[^ \t\r\n]+\\( +[^ \t\r\n]+\\) +"
+ "[^ \t\r\n]+ +[^ \t\r\n]+\\( +[0-9]+\\)")))
+ (goto-char beg)
+ (insert string)
+ (goto-char beg)
+ (or (looking-at "^")
(forward-line 1))
- ;; Convert ` ./FILE' to ` FILE'
- ;; This would lose if the current chunk of output
- ;; starts or ends within the ` ./', so back up a bit:
- (goto-char (- end 3)) ; no error if < 0
- (while (search-forward " ./" nil t)
- (delete-region (point) (- (point) 2)))
- ;; Find all the complete lines in the unprocessed
- ;; output and process it to add text properties.
- (goto-char (point-max))
- (if (search-backward "\n" (process-mark proc) t)
- (progn
- (dired-insert-set-properties (process-mark proc)
- (1+ (point)))
- (move-marker (process-mark proc) (1+ (point)))))
- ))))
+ (while (looking-at "^")
+ (insert " ")
+ (forward-line 1))
+ ;; Convert ` ./FILE' to ` FILE'
+ ;; This would lose if the current chunk of output
+ ;; starts or ends within the ` ./', so back up a bit:
+ (goto-char (- beg 3)) ; no error if < 0
+ (while (search-forward " ./" nil t)
+ (delete-region (point) (- (point) 2)))
+ ;; Pad the number of links and file size. This is a
+ ;; quick and dirty way of getting the columns to line up
+ ;; most of the time, but it's not foolproof.
+ (when l-opt
+ (goto-char beg)
+ (goto-char (line-beginning-position))
+ (while (re-search-forward ls-regexp nil t)
+ (replace-match (format "%4s" (match-string 1))
+ nil nil nil 1)
+ (replace-match (format "%9s" (match-string 2))
+ nil nil nil 2)
+ (forward-line 1)))
+ ;; Find all the complete lines in the unprocessed
+ ;; output and process it to add text properties.
+ (goto-char (point-max))
+ (if (search-backward "\n" (process-mark proc) t)
+ (progn
+ (dired-insert-set-properties (process-mark proc)
+ (1+ (point)))
+ (move-marker (process-mark proc) (1+ (point))))))))
;; The buffer has been killed.
(delete-process proc))))
("xt-mouse.el"
"support the mouse when emacs run in an xterm"
(mouse terminals))
- ("calc-aent.el"
- "algebraic entry functions for Calc"
- nil)
- ("calc-alg.el"
- "algebraic functions for Calc"
- nil)
- ("calc-arith.el"
- "arithmetic functions for Calc"
- nil)
- ("calc-bin.el"
- "binary functions for Calc"
- nil)
- ("calc-comb.el"
- "combinatoric functions for Calc"
+ ("crisp.el"
+ "CRiSP/Brief Emacs emulator"
+ (emulations brief crisp))
+ ("cua-base.el"
+ "emulate CUA key bindings"
+ (keyboard emulation convenience cua))
+ ("cua-gmrk.el"
+ "CUA unified global mark support"
+ (keyboard emulations convenience cua mark))
+ ("cua-rect.el"
+ "CUA unified rectangle support"
+ (keyboard emulations convenience cua))
+ ("edt-lk201.el"
+ "enhanced EDT keypad mode emulation for LK-201 keyboards"
+ (emulations))
+ ("edt-mapper.el"
+ "create an EDT LK-201 map file for X-Windows Emacs"
+ (emulations))
+ ("edt-pc.el"
+ "enhanced EDT keypad mode emulation for PC 101 keyboards"
+ (emulations))
+ ("edt-vt100.el"
+ "enhanced EDT keypad mode emulation for VT series terminals"
+ (emulations))
+ ("edt.el"
+ "enhanced EDT keypad mode emulation for GNU Emacs 19"
+ (emulations))
+ ("keypad.el"
+ "simplified keypad bindings"
+ (keyboard convenience))
+ ("pc-mode.el"
+ "emulate certain key bindings used on PCs"
+ (emulations))
+ ("pc-select.el"
+ "emulate mark, cut, copy and paste from Motif"
+ (convenience emulation))
+ ("tpu-edt.el"
+ "Emacs emulating TPU emulating EDT"
+ (emulations))
+ ("tpu-extras.el"
+ "scroll margins and free cursor mode for TPU-edt"
+ (emulations))
+ ("tpu-mapper.el"
+ "create a TPU-edt X-windows keymap file"
+ (emulations))
+ ("vi.el"
+ "major mode for emulating \"vi\" editor under GNU Emacs"
+ (emulations))
+ ("vip.el"
+ "a VI Package for GNU Emacs"
+ (emulations))
+ ("viper-cmd.el"
+ "Vi command support for Viper"
nil)
- ("calc-cplx.el"
- "Complex number functions for Calc"
+ ("viper-ex.el"
+ "functions implementing the Ex commands for Viper"
nil)
- ("calc-embed.el"
- "embed Calc in a buffer"
+ ("viper-init.el"
+ "some common definitions for Viper"
nil)
- ("calc-ext.el"
- "various extension functions for Calc"
+ ("viper-keym.el"
+ "Viper keymaps"
nil)
- ("calc-fin.el"
- "financial functions for Calc"
+ ("viper-macs.el"
+ "functions implementing keyboard macros for Viper"
nil)
- ("calc-forms.el"
- "data format conversion functions for Calc"
+ ("viper-mous.el"
+ "mouse support for Viper"
nil)
- ("calc-frac.el"
- "fraction functions for Calc"
+ ("viper-util.el"
+ "Utilities used by viper.el"
nil)
- ("calc-funcs.el"
- "well-known functions for Calc"
+ ("viper.el"
+ "A full-featured Vi emulator for GNU Emacs and XEmacs,"
+ (emulations))
+ ("ws-mode.el"
+ "WordStar emulation mode for GNU Emacs"
+ (emulations))
+ ("ada-mode.el"
+ "major-mode for editing Ada sources"
+ (languages ada))
+ ("ada-prj.el"
+ "GUI editing of project files for the ada-mode"
+ (languages ada project file))
+ ("ada-stmt.el"
+ "an extension to Ada mode for inserting statement templates"
+ (languages ada))
+ ("ada-xref.el"
+ "for lookup and completion in Ada mode"
+ (languages ada xref))
+ ("antlr-mode.el"
+ "major mode for ANTLR grammar files"
+ (languages antlr code generator))
+ ("asm-mode.el"
+ "mode for editing assembler code"
+ (tools languages))
+ ("autoconf.el"
+ "mode for editing Autoconf configure.in files"
+ (languages))
+ ("cc-align.el"
+ "custom indentation functions for CC Mode"
+ (c languages oop))
+ ("cc-awk.el"
+ "AWK specific code within cc-mode."
+ (awk cc-mode unix languages))
+ ("cc-bytecomp.el"
+ "compile time setup for proper compilation"
+ (c languages oop))
+ ("cc-cmds.el"
+ "user level commands for CC Mode"
+ (c languages oop))
+ ("cc-compat.el"
+ "cc-mode compatibility with c-mode.el confusion"
+ (c languages oop))
+ ("cc-defs.el"
+ "compile time definitions for CC Mode"
+ (c languages oop))
+ ("cc-engine.el"
+ "core syntax guessing engine for CC mode"
+ (c languages oop))
+ ("cc-fonts.el"
+ "font lock support for CC Mode"
+ (c languages oop))
+ ("cc-langs.el"
+ "language specific settings for CC Mode"
+ (c languages oop))
+ ("cc-menus.el"
+ "imenu support for CC Mode"
+ (c languages oop))
+ ("cc-mode.el"
+ "major mode for editing C and similar languages"
+ (c languages oop))
+ ("cc-styles.el"
+ "support for styles in CC Mode"
+ (c languages oop))
+ ("cc-subword.el"
+ "Handling capitalized subwords in a nomenclature"
nil)
- ("calc-graph.el"
- "graph output functions for Calc"
+ ("cc-vars.el"
+ "user customization variables for CC Mode"
+ (c languages oop))
+ ("cfengine.el"
+ "mode for editing Cfengine files"
+ (languages))
+ ("cmacexp.el"
+ "expand C macros in a region"
+ (c))
+ ("compile.el"
+ "run compiler as inferior of Emacs, parse error messages"
+ (tools processes))
+ ("cperl-mode.el"
+ "Perl code editing commands for Emacs"
+ (languages perl))
+ ("cpp.el"
+ "highlight or hide text according to cpp conditionals"
+ (c faces tools))
+ ("cwarn.el"
+ "highlight suspicious C and C++ constructions"
+ (c languages faces))
+ ("dcl-mode.el"
+ "major mode for editing DCL command files"
+ (dcl editing major-mode languages))
+ ("delphi.el"
+ "major mode for editing Delphi source (Object Pascal) in Emacs"
+ (languages))
+ ("ebnf-abn.el"
+ "parser for ABNF (Augmented BNF)"
+ (wp ebnf postscript))
+ ("ebnf-bnf.el"
+ "parser for EBNF"
+ (wp ebnf postscript))
+ ("ebnf-dtd.el"
+ "parser for DTD (Data Type Description for XML)"
+ (wp ebnf postscript))
+ ("ebnf-ebx.el"
+ "parser for EBNF used to specify XML (EBNFX)"
+ (wp ebnf postscript))
+ ("ebnf-iso.el"
+ "parser for ISO EBNF"
+ (wp ebnf postscript))
+ ("ebnf-otz.el"
+ "syntactic chart OpTimiZer"
+ (wp ebnf postscript))
+ ("ebnf-yac.el"
+ "parser for Yacc/Bison"
+ (wp ebnf postscript))
+ ("ebnf2ps.el"
+ "translate an EBNF to a syntactic chart on PostScript"
+ (wp ebnf postscript))
+ ("ebrowse.el"
+ "Emacs C++ class browser & tags facility"
+ (c++ tags tools))
+ ("etags.el"
+ "etags facility for Emacs"
+ (tools))
+ ("executable.el"
+ "base functionality for executable interpreter scripts"
+ (languages unix))
+ ("f90.el"
+ "Fortran-90 mode (free format)"
+ (fortran f90 languages))
+ ("flymake.el"
+ "a universal on-the-fly syntax checker"
+ (c languages tools))
+ ("fortran.el"
+ "Fortran mode for GNU Emacs"
+ (fortran languages))
+ ("gdb-ui.el"
+ "User Interface for running GDB"
+ (unix tools))
+ ("glasses.el"
+ "make cantReadThis readable"
+ (tools))
+ ("grep.el"
+ "run Grep as inferior of Emacs, parse match messages"
+ (tools processes))
+ ("gud.el"
+ "Grand Unified Debugger mode for running GDB and other debuggers"
+ (unix tools))
+ ("hideif.el"
+ "hides selected code within ifdef"
+ (c outlines))
+ ("hideshow.el"
+ "minor mode cmds to selectively display code/comment blocks"
+ (c c++ java lisp tools editing comments blocks hiding outlines))
+ ("icon.el"
+ "mode for editing Icon code"
+ (languages))
+ ("idlw-complete-structtag.el"
+ "Completion of structure tags."
+ (languages))
+ ("idlw-help.el"
+ "HTML Help code for IDLWAVE"
nil)
- ("calc-help.el"
- "help display functions for Calc,"
- nil)
- ("calc-incom.el"
- "complex data type input functions for Calc"
- nil)
- ("calc-keypd.el"
- "mouse-capable keypad input for Calc"
- nil)
- ("calc-lang.el"
- "calc language functions"
- nil)
- ("calc-macs.el"
- "important macros for Calc"
- nil)
- ("calc-map.el"
- "higher-order functions for Calc"
- nil)
- ("calc-math.el"
- "mathematical functions for Calc"
- nil)
- ("calc-misc.el"
- "miscellaneous functions for Calc"
- nil)
- ("calc-mode.el"
- "calculator modes for Calc"
- nil)
- ("calc-mtx.el"
- "matrix functions for Calc"
- nil)
- ("calc-poly.el"
- "polynomial functions for Calc"
- nil)
- ("calc-prog.el"
- "user programmability functions for Calc"
- nil)
- ("calc-rewr.el"
- "rewriting functions for Calc"
- nil)
- ("calc-rules.el"
- "rules for simplifying algebraic expressions in Calc"
- nil)
- ("calc-sel.el"
- "data selection functions for Calc"
- nil)
- ("calc-stat.el"
- "statistical functions for Calc"
- nil)
- ("calc-store.el"
- "value storage functions for Calc"
- nil)
- ("calc-stuff.el"
- "miscellaneous functions for Calc"
- nil)
- ("calc-trail.el"
- "functions for manipulating the Calc \"trail\""
- nil)
- ("calc-undo.el"
- "undo functions for Calc"
- nil)
- ("calc-units.el"
- "unit conversion functions for Calc"
- nil)
- ("calc-vec.el"
- "vector functions for Calc"
- nil)
- ("calc-yank.el"
- "kill-ring functionality for Calc"
- nil)
- ("calc.el"
- "the GNU Emacs calculator"
- (convenience extensions))
- ("calcalg2.el"
- "more algebraic functions for Calc"
- nil)
- ("calcalg3.el"
- "more algebraic functions for Calc"
- nil)
- ("calccomp.el"
- "composition functions for Calc"
- nil)
- ("calcsel2.el"
- "selection functions for Calc"
- nil)
- ("erc-autoaway.el"
- "Provides autoaway for ERC"
- nil)
- ("erc-backend.el"
- "Backend network communication for ERC"
- (irc chat client internet))
- ("erc-button.el"
- "A way of buttonizing certain things in ERC buffers"
- (irc button url regexp))
- ("erc-capab.el"
- "support for dancer-ircd and hyperion's CAPAB"
- nil)
- ("erc-compat.el"
- "ERC compatibility code for XEmacs"
- nil)
- ("erc-dcc.el"
- "CTCP DCC module for ERC"
- (comm processes))
- ("erc-ezbounce.el"
- "Handle EZBounce bouncer commands"
- (comm))
- ("erc-fill.el"
- "Filling IRC messages in various ways"
- nil)
- ("erc-goodies.el"
- "Collection of ERC modules"
- nil)
- ("erc-hecomplete.el"
- "Provides Nick name completion for ERC"
- nil)
- ("erc-ibuffer.el"
- "ibuffer integration with ERC"
- (comm))
- ("erc-identd.el"
- "RFC1413 (identd authentication protocol) server"
- (comm processes))
- ("erc-imenu.el"
- "Imenu support for ERC"
- (comm))
- ("erc-join.el"
- "autojoin channels on connect and reconnects"
- (irc))
- ("erc-lang.el"
- "provide the LANG command to ERC"
+ ("idlw-shell.el"
+ "run IDL as an inferior process of Emacs."
+ (processes))
+ ("idlw-toolbar.el"
+ "a debugging toolbar for IDLWAVE"
+ (processes))
+ ("idlwave.el"
+ "IDL editing mode for GNU Emacs"
+ (languages))
+ ("inf-lisp.el"
+ "an inferior-lisp mode"
+ (processes lisp))
+ ("ld-script.el"
+ "GNU linker script editing mode for Emacs"
+ (languages faces))
+ ("m4-mode.el"
+ "m4 code editing commands for Emacs"
+ (languages faces))
+ ("make-mode.el"
+ "makefile editing commands for Emacs"
+ (unix tools))
+ ("mantemp.el"
+ "create manual template instantiations from g++ 2.7.2 output"
+ (g++ templates))
+ ("meta-mode.el"
+ "major mode for editing Metafont or MetaPost sources"
+ (metafont metapost tex languages))
+ ("mixal-mode.el"
+ "Major mode for the mix asm language."
+ (knuth mix mixal asm mixvm "the art of computer programming"))
+ ("modula2.el"
+ "Modula-2 editing support package"
+ (languages))
+ ("octave-hlp.el"
+ "getting help on Octave symbols using info"
+ (languages))
+ ("octave-inf.el"
+ "running Octave as an inferior Emacs process"
+ (languages))
+ ("octave-mod.el"
+ "editing Octave source files under Emacs"
+ (languages))
+ ("pascal.el"
+ "major mode for editing pascal source in Emacs"
+ (languages))
+ ("perl-mode.el"
+ "Perl code editing commands for GNU Emacs"
+ (languages))
+ ("prolog.el"
+ "major mode for editing and running Prolog under Emacs"
+ (languages))
+ ("ps-mode.el"
+ "PostScript mode for GNU Emacs"
+ (postscript languages))
+ ("python.el"
+ "silly walks for Python"
+ (languages))
+ ("scheme.el"
+ "Scheme (and DSSSL) editing mode"
+ (languages lisp))
+ ("sh-script.el"
+ "shell-script editing commands for Emacs"
+ (languages unix))
+ ("simula.el"
+ "SIMULA 87 code editing commands for Emacs"
+ (languages))
+ ("sql.el"
+ "specialized comint.el for SQL interpreters"
(comm languages processes))
- ("erc-log.el"
- "Logging facilities for ERC."
- (irc chat client internet logging))
- ("erc-match.el"
- "Highlight messages matching certain regexps"
- (comm faces))
- ("erc-menu.el"
- "Menu-bar definitions for ERC"
- (comm processes menu))
- ("erc-netsplit.el"
- "Reduce JOIN/QUIT messages on netsplits"
- (comm))
- ("erc-networks.el"
- "IRC networks"
- (comm))
- ("erc-notify.el"
- "Online status change notification"
- (comm))
- ("erc-page.el"
- nil
- nil)
- ("erc-pcomplete.el"
- "Provides programmable completion for ERC"
- (comm convenience))
- ("erc-replace.el"
- "wash and massage messages inserted into the buffer"
- (irc client internet))
- ("erc-ring.el"
- "Command history handling for erc using ring.el"
- (comm))
- ("erc-services.el"
- "Identify to NickServ"
- nil)
- ("erc-sound.el"
- "CTCP SOUND support for ERC"
- nil)
- ("erc-speedbar.el"
- "Speedbar support for ERC"
- nil)
- ("erc-spelling.el"
- "use flyspell in ERC"
- (irc))
- ("erc-stamp.el"
- "Timestamping for ERC messages"
- (comm processes timestamp))
- ("erc-track.el"
- "Track modified channel buffers"
- (comm faces))
- ("erc-truncate.el"
- "Functions for truncating ERC buffers"
- (irc chat client internet logging))
- ("erc-xdcc.el"
- "XDCC file-server support for ERC"
- (comm processes))
- ("erc.el"
- "An Emacs Internet Relay Chat client"
- (irc chat client internet))
- ("binhex.el"
- "elisp native binhex decode"
- (binhex news))
- ("canlock.el"
- "functions for Cancel-Lock feature"
- (news cancel-lock hmac sha1 rfc2104))
- ("compface.el"
- "functions for converting X-Face headers"
- (news))
- ("deuglify.el"
- "deuglify broken Outlook (Express) articles"
- (mail news))
- ("dig.el"
- "Domain Name System dig interface"
- (dns bind dig))
- ("dns.el"
- "Domain Name Service lookups"
- (network))
- ("earcon.el"
- "Sound effects for messages"
- nil)
- ("flow-fill.el"
- "interpret RFC2646 \"flowed\" text"
- (mail))
- ("format-spec.el"
- "functions for formatting arbitrary formatting strings"
- (tools))
- ("gmm-utils.el"
- "Utility functions for Gnus, Message and MML"
- (news))
- ("gnus-agent.el"
- "unplugged support for Gnus"
- nil)
- ("gnus-art.el"
- "article mode commands for Gnus"
- (news))
- ("gnus-async.el"
- "asynchronous support for Gnus"
- (news))
- ("gnus-audio.el"
- "Sound effects for Gnus"
- (news mail multimedia))
- ("gnus-bcklg.el"
- "backlog functions for Gnus"
- (news))
- ("gnus-cache.el"
- "cache interface for Gnus"
- (news))
- ("gnus-cite.el"
- "parse citations in articles for Gnus"
- nil)
- ("gnus-cus.el"
- "customization commands for Gnus"
- (news))
- ("gnus-delay.el"
- "Delayed posting of articles"
- (mail news extensions))
- ("gnus-demon.el"
- "daemonic Gnus behaviour"
- (news))
- ("gnus-diary.el"
- "Wrapper around the NNDiary Gnus back end"
- (calendar mail news))
- ("gnus-dired.el"
- "utility functions where gnus and dired meet"
- (mail news extensions))
- ("gnus-draft.el"
- "draft message support for Gnus"
- (news))
- ("gnus-dup.el"
- "suppression of duplicate articles in Gnus"
- (news))
- ("gnus-eform.el"
- "a mode for editing forms for Gnus"
- (news))
- ("gnus-ems.el"
- "functions for making Gnus work under different Emacsen"
- (news))
- ("gnus-fun.el"
- "various frivolous extension functions to Gnus"
- (news))
- ("gnus-gl.el"
- "an interface to GroupLens for Gnus"
- (news score))
- ("gnus-group.el"
- "group mode commands for Gnus"
- (news))
- ("gnus-int.el"
- "backend interface functions for Gnus"
- (news))
- ("gnus-kill.el"
- "kill commands for Gnus"
- (news))
- ("gnus-logic.el"
- "advanced scoring code for Gnus"
- (news))
- ("gnus-mh.el"
- "mh-e interface for Gnus"
- (news))
- ("gnus-ml.el"
- "Mailing list minor mode for Gnus"
- (news mail))
- ("gnus-mlspl.el"
- "a group params-based mail splitting mechanism"
- (news mail))
- ("gnus-move.el"
- "commands for moving Gnus from one server to another"
- (news))
- ("gnus-msg.el"
- "mail and post interface for Gnus"
- (news))
- ("gnus-nocem.el"
- "NoCeM pseudo-cancellation treatment"
- (news))
- ("gnus-picon.el"
- "displaying pretty icons in Gnus"
- (news xpm annotation glyph faces))
- ("gnus-range.el"
- "range and sequence functions for Gnus"
- (news))
- ("gnus-registry.el"
- "article registry for Gnus"
- (news))
- ("gnus-salt.el"
- "alternate summary mode interfaces for Gnus"
- (news))
- ("gnus-score.el"
- "scoring code for Gnus"
- (news))
- ("gnus-setup.el"
- "Initialization & Setup for Gnus 5"
- (news))
- ("gnus-sieve.el"
- "Utilities to manage sieve scripts for Gnus"
- nil)
- ("gnus-soup.el"
- "SOUP packet writing support for Gnus"
- (news mail))
- ("gnus-spec.el"
- "format spec functions for Gnus"
- (news))
- ("gnus-srvr.el"
- "virtual server support for Gnus"
- (news))
- ("gnus-start.el"
- "startup functions for Gnus"
- (news))
- ("gnus-sum.el"
- "summary mode commands for Gnus"
- (news))
- ("gnus-topic.el"
- "a folding minor mode for Gnus group buffers"
- (news))
- ("gnus-undo.el"
- "minor mode for undoing in Gnus"
- (news))
- ("gnus-util.el"
- "utility functions for Gnus"
- (news))
- ("gnus-uu.el"
- "extract (uu)encoded files in Gnus"
- nil)
- ("gnus-vm.el"
- "vm interface for Gnus"
- (news mail))
- ("gnus-win.el"
- "window configuration functions for Gnus"
- (news))
- ("gnus.el"
- "a newsreader for GNU Emacs"
- (news mail))
- ("hex-util.el"
- "Functions to encode/decode hexadecimal string."
- (data))
- ("html2text.el"
- "a simple html to plain text converter"
- nil)
- ("ietf-drums.el"
- "Functions for parsing RFC822bis headers"
- nil)
- ("imap.el"
- "imap library"
- (mail))
- ("legacy-gnus-agent.el"
- "Legacy unplugged support for Gnus"
- (news))
- ("mail-parse.el"
- "Interface functions for parsing mail"
- nil)
- ("mail-prsvr.el"
- "Interface variables for parsing mail"
- nil)
- ("mail-source.el"
- "functions for fetching mail"
- (news mail))
- ("mailcap.el"
- "MIME media types configuration"
- (news mail multimedia))
- ("message.el"
- "composing mail and news messages"
- (mail news))
- ("messcompat.el"
- "making message mode compatible with mail mode"
- (mail news))
- ("mm-bodies.el"
- "Functions for decoding MIME things"
- nil)
- ("mm-decode.el"
- "Functions for decoding MIME things"
- nil)
- ("mm-encode.el"
- "Functions for encoding MIME things"
- nil)
- ("mm-extern.el"
- "showing message/external-body"
- (message external-body))
- ("mm-partial.el"
- "showing message/partial"
- (message partial))
- ("mm-url.el"
- "a wrapper of url functions/commands for Gnus"
- nil)
- ("mm-util.el"
- "Utility functions for Mule and low level things"
- nil)
- ("mm-uu.el"
- "Return uu stuff as mm handles"
- (postscript uudecode binhex shar forward gnatsweb pgp))
- ("mm-view.el"
- "functions for viewing MIME objects"
- nil)
- ("mml-sec.el"
- "A package with security functions for MML documents"
- nil)
- ("mml-smime.el"
- "S/MIME support for MML"
- (gnus mime s/mime mml))
- ("mml.el"
- "A package for parsing and validating MML documents"
- nil)
- ("mml1991.el"
- "Old PGP message format (RFC 1991) support for MML"
- nil)
- ("mml2015.el"
- "MIME Security with Pretty Good Privacy (PGP)"
- (pgp mime mml))
- ("nnagent.el"
- "offline backend for Gnus"
- (news mail))
- ("nnbabyl.el"
- "rmail mbox access for Gnus"
- (news mail))
- ("nndb.el"
- "nndb access for Gnus"
- (news))
- ("nndiary.el"
- "A diary back end for Gnus"
- (calendar mail news))
- ("nndir.el"
- "single directory newsgroup access for Gnus"
- (news))
- ("nndoc.el"
- "single file access for Gnus"
- (news))
- ("nndraft.el"
- "draft article access for Gnus"
- (news))
- ("nneething.el"
- "arbitrary file access for Gnus"
- (news mail))
- ("nnfolder.el"
- "mail folder access for Gnus"
- (mail))
- ("nngateway.el"
- "posting news via mail gateways"
- (news mail))
- ("nnheader.el"
- "header access macros for Gnus and its backends"
- (news))
- ("nnimap.el"
- "imap backend for Gnus"
- (mail))
- ("nnkiboze.el"
- "select virtual news access for Gnus"
- (news))
- ("nnlistserv.el"
- "retrieving articles via web mailing list archives"
- (news mail))
- ("nnmail.el"
- "mail support functions for the Gnus mail backends"
- (news mail))
- ("nnmaildir.el"
- "maildir backend for Gnus"
- nil)
- ("nnmbox.el"
- "mail mbox access for Gnus"
- (news mail))
- ("nnmh.el"
- "mhspool access for Gnus"
- (news mail))
- ("nnml.el"
- "mail spool access for Gnus"
- (news mail))
- ("nnnil.el"
- "empty backend for Gnus"
- nil)
- ("nnoo.el"
- "OO Gnus Backends"
- (news))
- ("nnrss.el"
- "interfacing with RSS"
- (rss))
- ("nnslashdot.el"
- "interfacing with Slashdot"
- (news))
- ("nnsoup.el"
- "SOUP access for Gnus"
- (news mail))
- ("nnspool.el"
- "spool access for GNU Emacs"
- (news))
- ("nntp.el"
- "nntp access for Gnus"
- (news))
- ("nnultimate.el"
- "interfacing with the Ultimate Bulletin Board system"
- (news))
- ("nnvirtual.el"
- "virtual newsgroups access for Gnus"
- (news))
- ("nnwarchive.el"
- "interfacing with web archives"
- (news egroups mail-archive))
- ("nnweb.el"
- "retrieving articles via web search engines"
- (news))
- ("nnwfm.el"
- "interfacing with a web forum"
- (news))
- ("pop3.el"
- "Post Office Protocol (RFC 1460) interface"
- (mail))
- ("qp.el"
- "Quoted-Printable functions"
- (mail extensions))
- ("rfc1843.el"
- "HZ (rfc1843) decoding"
- (news hz hz+ mail i18n))
- ("rfc2045.el"
- "Functions for decoding rfc2045 headers"
- nil)
- ("rfc2047.el"
- "functions for encoding and decoding rfc2047 messages"
- nil)
- ("rfc2104.el"
- "RFC2104 Hashed Message Authentication Codes"
- (mail))
- ("rfc2231.el"
- "Functions for decoding rfc2231 headers"
- nil)
- ("score-mode.el"
- "mode for editing Gnus score files"
- (news mail))
- ("sha1.el"
- "SHA1 Secure Hash Algorithm in Emacs-Lisp"
- (sha1 fips 180-1))
- ("sieve-manage.el"
- "Implementation of the managesive protocol in elisp"
- nil)
- ("sieve-mode.el"
- "Sieve code editing commands for Emacs"
- nil)
- ("sieve.el"
- "Utilities to manage sieve scripts"
- nil)
- ("smiley.el"
- "displaying smiley faces"
- (news mail multimedia))
- ("smime.el"
- "S/MIME support library"
- (smime x.509 pem openssl))
- ("spam-report.el"
- "Reporting spam"
- (network))
- ("spam-stat.el"
- "detecting spam based on statistics"
- (network))
- ("spam.el"
- "Identifying spam"
- (network))
- ("starttls.el"
- "STARTTLS functions"
- (tls ssl openssl gnutls mail news))
- ("utf7.el"
- "UTF-7 encoding/decoding for Emacs"
- (mail))
- ("uudecode.el"
- "elisp native uudecode"
- (uudecode news))
- ("webmail.el"
- "interface of web mail"
- (hotmail netaddress my-deja netscape))
- ("yenc.el"
- "elisp native yenc decoder"
- (yenc news))
+ ("tcl.el"
+ "Tcl code editing commands for Emacs"
+ (languages tcl modes))
+ ("vera-mode.el"
+ "major mode for editing Vera files."
+ (languages vera))
+ ("verilog-mode.el"
+ "major mode for editing verilog source in Emacs"
+ (languages))
+ ("vhdl-mode.el"
+ "major mode for editing VHDL code"
+ (languages vhdl))
+ ("which-func.el"
+ "print current function in mode line"
+ (mode-line imenu tools))
+ ("xscheme.el"
+ "run MIT Scheme under Emacs"
+ (languages lisp))
("blessmail.el"
"decide whether movemail needs special privileges"
(internal))
("vms-pmail.el"
"use Emacs as the editor within VMS mail"
(vms))
+ ("5x5.el"
+ "simple little puzzle game"
+ (games puzzles))
+ ("animate.el"
+ "make text dance"
+ (games))
+ ("blackbox.el"
+ "blackbox game in Emacs Lisp"
+ (games))
+ ("bruce.el"
+ "bruce phrase utility for overloading the Communications"
+ (games))
+ ("cookie1.el"
+ "retrieve random phrases from fortune cookie files"
+ (games extensions))
+ ("decipher.el"
+ "cryptanalyze monoalphabetic substitution ciphers"
+ (games))
+ ("dissociate.el"
+ "scramble text amusingly for Emacs"
+ (games))
+ ("doctor.el"
+ "psychological help for frustrated users"
+ (games))
+ ("dunnet.el"
+ "text adventure for Emacs"
+ (games))
+ ("fortune.el"
+ "use fortune to create signatures"
+ (games utils mail))
+ ("gamegrid.el"
+ "library for implementing grid-based games on Emacs"
+ (games))
+ ("gametree.el"
+ "manage game analysis trees in Emacs"
+ (games))
+ ("gomoku.el"
+ "Gomoku game between you and Emacs"
+ (games))
+ ("handwrite.el"
+ "turns your emacs buffer into a handwritten document"
+ (wp print postscript cursive writing))
+ ("hanoi.el"
+ "towers of hanoi in Emacs"
+ (games))
+ ("landmark.el"
+ "neural-network robot that learns landmarks"
+ (gomoku neural network adaptive search chemotaxis))
+ ("life.el"
+ "John Horton Conway's `Life' game for GNU Emacs"
+ (games))
+ ("meese.el"
+ "protect the impressionable young minds of America"
+ (games))
+ ("morse.el"
+ "convert text to morse code and back"
+ (games))
+ ("mpuz.el"
+ "multiplication puzzle for GNU Emacs"
+ (games))
+ ("pong.el"
+ "classical implementation of pong"
+ (games))
+ ("snake.el"
+ "implementation of Snake for Emacs"
+ (games))
+ ("solitaire.el"
+ "game of solitaire in Emacs Lisp"
+ (games))
+ ("spook.el"
+ "spook phrase utility for overloading the NSA line eater"
+ (games))
+ ("studly.el"
+ "StudlyCaps (tm)(r)(c)(xxx)"
+ (games))
+ ("tetris.el"
+ "implementation of Tetris for Emacs"
+ (games))
+ ("yow.el"
+ "quote random zippyisms"
+ (games))
+ ("zone.el"
+ "idle display hacks"
+ (games))
("appt.el"
"appointment notification functions"
(calendar))
("todo-mode.el"
"major mode for editing TODO list files"
(calendar todo))
- ("advice.el"
- "an overloading mechanism for Emacs Lisp functions"
- (extensions lisp tools))
- ("assoc.el"
- "insert/delete/sort functions on association lists"
- (extensions))
- ("authors.el"
- "utility for maintaining Emacs' AUTHORS file"
- (maint))
- ("autoload.el"
- "maintain autoloads in loaddefs.el"
- (maint))
- ("backquote.el"
- "implement the ` Lisp construct"
- (extensions internal))
- ("benchmark.el"
- "support for benchmarking code"
- (lisp extensions))
- ("bindat.el"
- "binary data structure packing and unpacking."
- (comm data processes))
- ("byte-opt.el"
- "the optimization passes of the emacs-lisp byte compiler"
- (internal))
- ("byte-run.el"
- "byte-compiler support for inlining"
- (internal))
- ("bytecomp.el"
- "compilation of Lisp code into byte code"
- (lisp))
- ("checkdoc.el"
- "check documentation strings for style requirements"
- (docs maint lisp))
- ("cl-compat.el"
- "Common Lisp extensions for GNU Emacs Lisp (compatibility)"
- (extensions))
- ("cl-extra.el"
- "Common Lisp features, part 2"
- (extensions))
- ("cl-indent.el"
- "enhanced lisp-indent mode"
- (lisp tools))
- ("cl-loaddefs.el"
+ ("erc-autoaway.el"
+ "Provides autoaway for ERC"
+ nil)
+ ("erc-backend.el"
+ "Backend network communication for ERC"
+ (irc chat client internet))
+ ("erc-button.el"
+ "A way of buttonizing certain things in ERC buffers"
+ (irc button url regexp))
+ ("erc-capab.el"
+ "support for dancer-ircd and hyperion's CAPAB"
+ nil)
+ ("erc-compat.el"
+ "ERC compatibility code for XEmacs"
+ nil)
+ ("erc-dcc.el"
+ "CTCP DCC module for ERC"
+ (comm processes))
+ ("erc-ezbounce.el"
+ "Handle EZBounce bouncer commands"
+ (comm))
+ ("erc-fill.el"
+ "Filling IRC messages in various ways"
+ nil)
+ ("erc-goodies.el"
+ "Collection of ERC modules"
+ nil)
+ ("erc-hecomplete.el"
+ "Provides Nick name completion for ERC"
+ nil)
+ ("erc-ibuffer.el"
+ "ibuffer integration with ERC"
+ (comm))
+ ("erc-identd.el"
+ "RFC1413 (identd authentication protocol) server"
+ (comm processes))
+ ("erc-imenu.el"
+ "Imenu support for ERC"
+ (comm))
+ ("erc-join.el"
+ "autojoin channels on connect and reconnects"
+ (irc))
+ ("erc-lang.el"
+ "provide the LANG command to ERC"
+ (comm languages processes))
+ ("erc-log.el"
+ "Logging facilities for ERC."
+ (irc chat client internet logging))
+ ("erc-match.el"
+ "Highlight messages matching certain regexps"
+ (comm faces))
+ ("erc-menu.el"
+ "Menu-bar definitions for ERC"
+ (comm processes menu))
+ ("erc-netsplit.el"
+ "Reduce JOIN/QUIT messages on netsplits"
+ (comm))
+ ("erc-networks.el"
+ "IRC networks"
+ (comm))
+ ("erc-notify.el"
+ "Online status change notification"
+ (comm))
+ ("erc-page.el"
+ nil
+ nil)
+ ("erc-pcomplete.el"
+ "Provides programmable completion for ERC"
+ (comm convenience))
+ ("erc-replace.el"
+ "wash and massage messages inserted into the buffer"
+ (irc client internet))
+ ("erc-ring.el"
+ "Command history handling for erc using ring.el"
+ (comm))
+ ("erc-services.el"
+ "Identify to NickServ"
+ nil)
+ ("erc-sound.el"
+ "CTCP SOUND support for ERC"
+ nil)
+ ("erc-speedbar.el"
+ "Speedbar support for ERC"
+ nil)
+ ("erc-spelling.el"
+ "use flyspell in ERC"
+ (irc))
+ ("erc-stamp.el"
+ "Timestamping for ERC messages"
+ (comm processes timestamp))
+ ("erc-track.el"
+ "Track modified channel buffers"
+ (comm faces))
+ ("erc-truncate.el"
+ "Functions for truncating ERC buffers"
+ (irc chat client internet logging))
+ ("erc-xdcc.el"
+ "XDCC file-server support for ERC"
+ (comm processes))
+ ("erc.el"
+ "An Emacs Internet Relay Chat client"
+ (irc chat client internet))
+ ("mh-acros.el"
+ "macros used in MH-E"
+ (mail))
+ ("mh-alias.el"
+ "MH-E mail alias completion and expansion"
+ (mail))
+ ("mh-buffers.el"
+ "MH-E buffer constants and utilities"
+ (mail))
+ ("mh-comp.el"
+ "MH-E functions for composing and sending messages"
+ (mail))
+ ("mh-compat.el"
+ "make MH-E compatibile with various versions of Emacs"
+ (mail))
+ ("mh-e.el"
+ "GNU Emacs interface to the MH mail system"
+ (mail))
+ ("mh-folder.el"
+ "MH-Folder mode"
+ (mail))
+ ("mh-funcs.el"
+ "MH-E functions not everyone will use right away"
+ (mail))
+ ("mh-gnus.el"
+ "make MH-E compatible with various versions of Gnus"
+ (mail))
+ ("mh-identity.el"
+ "multiple identify support for MH-E"
+ (mail))
+ ("mh-inc.el"
+ "MH-E \"inc\" and separate mail spool handling"
+ (mail))
+ ("mh-junk.el"
+ "MH-E interface to anti-spam measures"
+ (mail spam))
+ ("mh-letter.el"
+ "MH-Letter mode"
+ (mail))
+ ("mh-limit.el"
+ "MH-E display limits"
+ (mail))
+ ("mh-loaddefs.el"
"automatically extracted autoloads"
+ (mail))
+ ("mh-mime.el"
+ "MH-E MIME support"
+ (mail))
+ ("mh-print.el"
+ "MH-E printing support"
+ (mail))
+ ("mh-scan.el"
+ "MH-E scan line constants and utilities"
+ (mail))
+ ("mh-search.el"
+ "MH-Search mode"
+ (mail))
+ ("mh-seq.el"
+ "MH-E sequences support"
+ (mail))
+ ("mh-show.el"
+ "MH-Show mode"
+ (mail))
+ ("mh-speed.el"
+ "MH-E speedbar support"
+ (mail))
+ ("mh-thread.el"
+ "MH-E threading support"
+ (mail))
+ ("mh-tool-bar.el"
+ "MH-E tool bar support"
+ (mail))
+ ("mh-utils.el"
+ "MH-E general utilities"
+ (mail))
+ ("mh-xface.el"
+ "MH-E X-Face and Face header field display"
+ (mail))
+ ("url-about.el"
+ "Show internal URLs"
+ (comm data processes hypermedia))
+ ("url-auth.el"
+ "Uniform Resource Locator authorization modules"
+ (comm data processes hypermedia))
+ ("url-cache.el"
+ "Uniform Resource Locator retrieval tool"
+ (comm data processes hypermedia))
+ ("url-cid.el"
+ "Content-ID URL loader"
+ (comm data processes))
+ ("url-cookie.el"
+ "Netscape Cookie support"
+ (comm data processes hypermedia))
+ ("url-dav.el"
+ "WebDAV support"
+ (url vc))
+ ("url-dired.el"
+ "URL Dired minor mode"
+ (comm files))
+ ("url-expand.el"
+ "expand-file-name for URLs"
+ (comm data processes))
+ ("url-file.el"
+ "File retrieval code"
+ (comm data processes))
+ ("url-ftp.el"
+ "FTP wrapper"
+ (comm data processes))
+ ("url-gw.el"
+ "Gateway munging for URL loading"
+ (comm data processes))
+ ("url-handlers.el"
+ "file-name-handler stuff for URL loading"
+ (comm data processes hypermedia))
+ ("url-history.el"
+ "Global history tracking for URL package"
+ (comm data processes hypermedia))
+ ("url-http.el"
+ "HTTP retrieval routines"
+ (comm data processes))
+ ("url-imap.el"
+ "IMAP retrieval routines"
+ (comm data processes))
+ ("url-irc.el"
+ "IRC URL interface"
+ (comm data processes))
+ ("url-ldap.el"
+ "LDAP Uniform Resource Locator retrieval code"
+ (comm data processes))
+ ("url-mailto.el"
+ "Mail Uniform Resource Locator retrieval code"
+ (comm data processes))
+ ("url-methods.el"
+ "Load URL schemes as needed"
+ (comm data processes hypermedia))
+ ("url-misc.el"
+ "Misc Uniform Resource Locator retrieval code"
+ (comm data processes))
+ ("url-news.el"
+ "News Uniform Resource Locator retrieval code"
+ (comm data processes))
+ ("url-nfs.el"
+ "NFS URL interface"
+ (comm data processes))
+ ("url-ns.el"
+ "Various netscape-ish functions for proxy definitions"
+ (comm data processes hypermedia))
+ ("url-parse.el"
+ "Uniform Resource Locator parser"
+ (comm data processes))
+ ("url-privacy.el"
+ "Global history tracking for URL package"
+ (comm data processes hypermedia))
+ ("url-proxy.el"
+ "Proxy server support"
+ (comm data processes hypermedia))
+ ("url-util.el"
+ "Miscellaneous helper routines for URL library"
+ (comm data processes))
+ ("url-vars.el"
+ "Variables for Uniform Resource Locator tool"
+ (comm data processes hypermedia))
+ ("url.el"
+ "Uniform Resource Locator retrieval tool"
+ (comm data processes hypermedia))
+ ("vc-dav.el"
+ "vc.el support for WebDAV"
+ (url vc))
+ ("china-util.el"
+ "utilities for Chinese"
+ (mule multilingual chinese))
+ ("chinese.el"
+ "support for Chinese"
+ (multilingual chinese))
+ ("cyril-util.el"
+ "utilities for Cyrillic scripts"
+ (mule multilingual cyrillic))
+ ("cyrillic.el"
+ "support for Cyrillic"
+ (multilingual cyrillic i18n))
+ ("czech.el"
+ "support for Czech"
+ (multilingual czech))
+ ("devan-util.el"
+ "Support for composing Devanagari characters"
+ (multilingual devanagari))
+ ("devanagari.el"
+ "Support for Devanagari"
+ (multilingual indian devanagari))
+ ("english.el"
+ "support for English"
+ (multibyte character character set syntax category))
+ ("ethio-util.el"
+ "utilities for Ethiopic"
+ (mule multilingual ethiopic))
+ ("ethiopic.el"
+ "support for Ethiopic"
+ (multilingual ethiopic))
+ ("european.el"
+ "support for European languages"
+ (multilingual european))
+ ("georgian.el"
+ "language support for Georgian"
+ (i18n))
+ ("greek.el"
+ "support for Greek"
+ (multilingual greek))
+ ("hebrew.el"
+ "support for Hebrew"
+ (multilingual hebrew))
+ ("ind-util.el"
+ "Transliteration and Misc. Tools for Indian Languages"
+ (multilingual indian devanagari))
+ ("indian.el"
+ "Indian languages support"
+ (multilingual i18n indian))
+ ("japan-util.el"
+ "utilities for Japanese"
+ (mule multilingual japanese))
+ ("japanese.el"
+ "support for Japanese"
+ (multilingual japanese))
+ ("kannada.el"
+ "Support for Kannada"
+ (multilingual indian kannada))
+ ("knd-util.el"
+ "Support for composing Kannada characters"
+ (multilingual kannada))
+ ("korea-util.el"
+ "utilities for Korean"
+ (mule multilingual korean))
+ ("korean.el"
+ "support for Korean"
+ (multilingual korean))
+ ("lao-util.el"
+ "utilities for Lao"
+ (multilingual lao))
+ ("lao.el"
+ "support for Lao"
+ (multilingual lao))
+ ("malayalam.el"
+ "Support for Malayalam"
+ (multilingual indian malayalam))
+ ("misc-lang.el"
+ "support for miscellaneous languages (characters)"
+ (multilingual character set coding system))
+ ("mlm-util.el"
+ "support for composing malayalam characters"
+ (multilingual malayalam))
+ ("romanian.el"
+ "support for Romanian"
+ (multilingual romanian))
+ ("slovak.el"
+ "support for Slovak"
+ (multilingual slovak))
+ ("tamil.el"
+ "Support for Tamil"
+ (multilingual indian tamil))
+ ("thai-util.el"
+ "utilities for Thai"
+ (mule multilingual thai))
+ ("thai-word.el"
+ "find Thai word boundaries"
+ (thai word break emacs))
+ ("thai.el"
+ "support for Thai"
+ (multilingual thai))
+ ("tibet-util.el"
+ "utilities for Tibetan"
+ (multilingual tibetan))
+ ("tibetan.el"
+ "support for Tibetan language"
+ (multilingual tibetan))
+ ("tml-util.el"
+ "support for composing tamil characters"
+ (multilingual indian tamil))
+ ("utf-8-lang.el"
+ "generic UTF-8 language environment"
+ (i18n))
+ ("viet-util.el"
+ "utilities for Vietnamese"
+ (mule multilingual vietnamese))
+ ("vietnamese.el"
+ "support for Vietnamese"
+ (multilingual vietnamese))
+ ("em-alias.el"
+ "creation and management of command aliases"
nil)
- ("cl-macs.el"
- "Common Lisp macros"
- (extensions))
- ("cl-seq.el"
- "Common Lisp features, part 3"
- (extensions))
- ("cl-specs.el"
- "Edebug specs for cl.el"
- (lisp tools maint))
- ("cl.el"
- "Common Lisp extensions for Emacs"
- (extensions))
- ("copyright.el"
- "update the copyright notice in current buffer"
- (maint tools))
- ("crm.el"
- "read multiple strings with completion"
- (completion minibuffer multiple elements))
- ("cust-print.el"
- "handles print-level and print-circle"
- (extensions))
- ("debug.el"
- "debuggers and related commands for Emacs"
- (lisp tools maint))
- ("derived.el"
- "allow inheritance of major modes"
- (extensions))
- ("disass.el"
- "disassembler for compiled Emacs Lisp code"
- (internal))
- ("easy-mmode.el"
- "easy definition for major and minor modes"
- (extensions lisp))
- ("easymenu.el"
- "support the easymenu interface for defining a menu"
- (emulations))
- ("edebug.el"
- "a source-level debugger for Emacs Lisp"
- (lisp tools maint))
- ("eldoc.el"
- "show function arglist or variable docstring in echo area"
- (extensions))
- ("elint.el"
- "Lint Emacs Lisp"
- (lisp))
- ("elp.el"
- "Emacs Lisp Profiler"
- (debugging lisp tools))
- ("ewoc.el"
- "utility to maintain a view of a list of objects in a buffer"
- (extensions lisp))
- ("find-func.el"
- "find the definition of the Emacs Lisp function near point"
- (emacs-lisp functions variables))
- ("find-gc.el"
- "detect functions that call the garbage collector"
+ ("em-banner.el"
+ "sample module that displays a login banner"
nil)
- ("float-sup.el"
- "define some constants useful for floating point numbers."
- (internal))
- ("generic.el"
- "defining simple major modes with comment and font-lock"
- (generic comment font-lock))
- ("gulp.el"
- "ask for updates for Lisp packages"
- (maintenance))
- ("helper.el"
- "utility help package supporting help in electric modes"
- (help))
- ("levents.el"
- "emulate the Lucid event data type and associated functions"
- (emulations))
- ("lisp-mnt.el"
- "utility functions for Emacs Lisp maintainers"
- (docs))
- ("lisp-mode.el"
- "Lisp mode, and its idiosyncratic commands"
- (lisp languages))
- ("lisp.el"
- "Lisp editing commands for Emacs"
- (lisp languages))
- ("lmenu.el"
- "emulate Lucid's menubar support"
- (emulations obsolete))
- ("lselect.el"
- "Lucid interface to X Selections"
- (emulations))
- ("lucid.el"
- "emulate some Lucid Emacs functions"
- (emulations))
- ("macroexp.el"
- "Additional macro-expansion support"
- (lisp compiler macros))
- ("map-ynp.el"
- "general-purpose boolean question-asker"
- (lisp extensions))
- ("pp.el"
- "pretty printer for Emacs Lisp"
- (lisp))
- ("re-builder.el"
- "building Regexps with visual feedback"
- (matching lisp tools))
- ("regexp-opt.el"
- "generate efficient regexps to match strings"
- (strings regexps extensions))
- ("regi.el"
- "REGular expression Interpreting engine"
- (extensions matching))
- ("ring.el"
- "handle rings of items"
- (extensions))
- ("rx.el"
- "sexp notation for regular expressions"
- (strings regexps extensions))
- ("shadow.el"
- "locate Emacs Lisp file shadowings"
- (lisp))
- ("sregex.el"
- "symbolic regular expressions"
- (extensions))
- ("syntax.el"
- "helper functions to find syntactic context"
- (internal))
- ("tcover-ses.el"
- "Example use of `testcover' to test \"SES\""
- (spreadsheet lisp utility))
- ("tcover-unsafep.el"
- "Use testcover to test unsafep's code coverage"
- (safety lisp utility))
- ("testcover.el"
- "Visual code-coverage tool"
- (lisp utility))
- ("timer.el"
- "run a function with args at some time in future"
+ ("em-basic.el"
+ "basic shell builtin commands"
+ nil)
+ ("em-cmpl.el"
+ "completion using the TAB key"
+ nil)
+ ("em-dirs.el"
+ "directory navigation commands"
+ nil)
+ ("em-glob.el"
+ "extended file name globbing"
+ nil)
+ ("em-hist.el"
+ "history list management"
+ nil)
+ ("em-ls.el"
+ "implementation of ls in Lisp"
+ nil)
+ ("em-pred.el"
+ "argument predicates and modifiers (ala zsh)"
+ nil)
+ ("em-prompt.el"
+ "command prompts"
+ nil)
+ ("em-rebind.el"
+ "rebind keys when point is at current input"
+ nil)
+ ("em-script.el"
+ "Eshell script files"
+ nil)
+ ("em-smart.el"
+ "smart display of output"
+ nil)
+ ("em-term.el"
+ "running visual commands"
+ nil)
+ ("em-unix.el"
+ "UNIX command aliases"
+ nil)
+ ("em-xtra.el"
+ "extra alias functions"
+ nil)
+ ("esh-arg.el"
+ "argument processing"
+ nil)
+ ("esh-cmd.el"
+ "command invocation"
+ nil)
+ ("esh-ext.el"
+ "commands external to Eshell"
+ nil)
+ ("esh-groups.el"
+ nil
+ nil)
+ ("esh-io.el"
+ "I/O management"
+ nil)
+ ("esh-maint.el"
+ "init code for building eshell"
+ nil)
+ ("esh-mode.el"
+ "user interface"
+ nil)
+ ("esh-module.el"
+ "Eshell modules"
+ (processes))
+ ("esh-opt.el"
+ "command options processing"
+ nil)
+ ("esh-proc.el"
+ "process management"
+ nil)
+ ("esh-test.el"
+ "Eshell test suite"
+ nil)
+ ("esh-util.el"
+ "general utilities"
+ nil)
+ ("esh-var.el"
+ "handling of variables"
+ nil)
+ ("eshell.el"
+ "the Emacs command shell"
+ (processes))
+ ("artist.el"
+ "draw ascii graphics with your mouse"
+ (mouse))
+ ("bib-mode.el"
+ "major mode for editing bib files"
+ (bib))
+ ("bibtex-style.el"
+ "Major mode for BibTeX Style files"
+ nil)
+ ("bibtex.el"
+ "BibTeX mode for GNU Emacs"
+ (bibtex latex tex))
+ ("conf-mode.el"
+ "Simple major mode for editing conf/ini/properties files"
+ (conf ini windows java))
+ ("css-mode.el"
+ "Major mode to edit CSS files"
+ (hypermedia))
+ ("dns-mode.el"
+ "a mode for viewing/editing Domain Name System master files"
+ (dns master zone file soa))
+ ("enriched.el"
+ "read and save files in text/enriched format"
+ (wp faces))
+ ("fill.el"
+ "fill commands for Emacs"
+ (wp))
+ ("flyspell.el"
+ "on-the-fly spell checker"
+ (convenience))
+ ("ispell.el"
+ "interface to International Ispell Versions 3.1 and 3.2"
+ (unix wp))
+ ("makeinfo.el"
+ "run makeinfo conveniently"
+ (docs convenience))
+ ("nroff-mode.el"
+ "GNU Emacs major mode for editing nroff source"
+ (wp))
+ ("org-export-latex.el"
+ "LaTeX exporter for org-mode"
+ (org wp tex))
+ ("org-irc.el"
+ "Store links to IRC sessions"
+ (erc irc link org))
+ ("org-mac-message.el"
+ "Support for links to Apple Mail messages by Message-ID"
+ (outlines hypermedia calendar wp))
+ ("org-mouse.el"
+ "Better mouse support for org-mode"
nil)
- ("tq.el"
- "utility to maintain a transaction queue"
- (extensions))
- ("trace.el"
- "tracing facility for Emacs Lisp functions"
- (tools lisp))
- ("unsafep.el"
- "Determine whether a Lisp form is safe to evaluate"
- (safety lisp utility))
- ("warnings.el"
- "log and display warnings"
- (internal))
- ("crisp.el"
- "CRiSP/Brief Emacs emulator"
- (emulations brief crisp))
- ("cua-base.el"
- "emulate CUA key bindings"
- (keyboard emulation convenience cua))
- ("cua-gmrk.el"
- "CUA unified global mark support"
- (keyboard emulations convenience cua mark))
- ("cua-rect.el"
- "CUA unified rectangle support"
- (keyboard emulations convenience cua))
- ("edt-lk201.el"
- "enhanced EDT keypad mode emulation for LK-201 keyboards"
- (emulations))
- ("edt-mapper.el"
- "create an EDT LK-201 map file for X-Windows Emacs"
- (emulations))
- ("edt-pc.el"
- "enhanced EDT keypad mode emulation for PC 101 keyboards"
- (emulations))
- ("edt-vt100.el"
- "enhanced EDT keypad mode emulation for VT series terminals"
- (emulations))
- ("edt.el"
- "enhanced EDT keypad mode emulation for GNU Emacs 19"
- (emulations))
- ("keypad.el"
- "simplified keypad bindings"
- (keyboard convenience))
- ("pc-mode.el"
- "emulate certain key bindings used on PCs"
- (emulations))
- ("pc-select.el"
- "emulate mark, cut, copy and paste from Motif"
- (convenience emulation))
- ("tpu-edt.el"
- "Emacs emulating TPU emulating EDT"
- (emulations))
- ("tpu-extras.el"
- "scroll margins and free cursor mode for TPU-edt"
- (emulations))
- ("tpu-mapper.el"
- "create a TPU-edt X-windows keymap file"
- (emulations))
- ("vi.el"
- "major mode for emulating \"vi\" editor under GNU Emacs"
- (emulations))
- ("vip.el"
- "a VI Package for GNU Emacs"
- (emulations))
- ("viper-cmd.el"
- "Vi command support for Viper"
+ ("org-publish.el"
+ "publish related org-mode files as a website"
+ (hypermedia outlines wp))
+ ("org.el"
+ "Outline-based notes management and organizer"
+ (outlines hypermedia calendar wp))
+ ("page-ext.el"
+ "extended page handling commands"
+ (wp data))
+ ("page.el"
+ "page motion commands for Emacs"
+ (wp convenience))
+ ("paragraphs.el"
+ "paragraph and sentence parsing"
+ (wp))
+ ("picture.el"
+ "\"Picture mode\" -- editing using quarter-plane screen model"
+ (convenience wp))
+ ("po.el"
+ "basic support of PO translation files"
+ (i18n files))
+ ("refbib.el"
+ "convert refer-style references to ones usable by Latex bib"
+ (bib tex))
+ ("refer.el"
+ "look up references in bibliography files"
+ (bib))
+ ("refill.el"
+ "`auto-fill' by refilling paragraphs on changes"
+ (wp))
+ ("reftex-auc.el"
+ "RefTeX's interface to AUCTeX"
+ nil)
+ ("reftex-cite.el"
+ "creating citations with RefTeX"
+ nil)
+ ("reftex-dcr.el"
+ "viewing cross references and citations with RefTeX"
+ nil)
+ ("reftex-global.el"
+ "operations on entire documents with RefTeX"
+ nil)
+ ("reftex-index.el"
+ "index support with RefTeX"
+ nil)
+ ("reftex-parse.el"
+ "parser functions for RefTeX"
+ nil)
+ ("reftex-ref.el"
+ "code to create labels and references with RefTeX"
+ nil)
+ ("reftex-sel.el"
+ "the selection modes for RefTeX"
+ nil)
+ ("reftex-toc.el"
+ "RefTeX's table of contents mode"
+ nil)
+ ("reftex-vars.el"
+ "configuration variables for RefTeX"
+ nil)
+ ("reftex.el"
+ "minor mode for doing \\label, \\ref, \\cite, \\index in LaTeX"
+ (tex))
+ ("sgml-mode.el"
+ "SGML- and HTML-editing modes"
+ (wp hypermedia comm languages))
+ ("spell.el"
+ "spelling correction interface for Emacs"
+ (wp unix))
+ ("table.el"
+ "create and edit WYSIWYG text based embedded tables"
+ (wp convenience))
+ ("tex-mode.el"
+ "TeX, LaTeX, and SliTeX mode commands"
+ (tex))
+ ("texinfmt.el"
+ "format Texinfo files into Info files"
+ (maint tex docs))
+ ("texinfo.el"
+ "major mode for editing Texinfo files"
+ (maint tex docs))
+ ("texnfo-upd.el"
+ "utilities for updating nodes and menus in Texinfo files"
+ (maint tex docs))
+ ("text-mode.el"
+ "text mode, and its idiosyncratic commands"
+ (wp))
+ ("tildify.el"
+ "adding hard spaces into texts"
+ (text tex sgml wp))
+ ("two-column.el"
+ "minor mode for editing of two-column text"
+ (wp))
+ ("underline.el"
+ "insert/remove underlining (done by overstriking) in Emacs"
+ (wp))
+ ("ange-ftp.el"
+ "transparent FTP support for GNU Emacs"
+ (comm))
+ ("browse-url.el"
+ "pass a URL to a WWW browser"
+ (hypertext hypermedia mouse))
+ ("eudc-bob.el"
+ "Binary Objects Support for EUDC"
+ (comm))
+ ("eudc-export.el"
+ "functions to export EUDC query results"
+ (comm))
+ ("eudc-hotlist.el"
+ "hotlist management for EUDC"
+ (comm))
+ ("eudc-vars.el"
+ "Emacs Unified Directory Client"
+ (comm))
+ ("eudc.el"
+ "Emacs Unified Directory Client"
+ (comm))
+ ("eudcb-bbdb.el"
+ "Emacs Unified Directory Client - BBDB Backend"
+ (comm))
+ ("eudcb-ldap.el"
+ "Emacs Unified Directory Client - LDAP Backend"
+ (comm))
+ ("eudcb-mab.el"
+ "Emacs Unified Directory Client - AddressBook backend"
+ (comm))
+ ("eudcb-ph.el"
+ "Emacs Unified Directory Client - CCSO PH/QI Backend"
+ (comm))
+ ("goto-addr.el"
+ "click to browse URL or to send to e-mail address"
+ (mh-e www mouse mail))
+ ("ldap.el"
+ "client interface to LDAP for Emacs"
+ (comm))
+ ("net-utils.el"
+ "network functions"
+ (network comm))
+ ("netrc.el"
+ ".netrc parsing functionality"
+ (news))
+ ("newsticker.el"
+ "A Newsticker for Emacs."
+ (news rss atom))
+ ("quickurl.el"
+ "insert an URL based on text at point in buffer"
+ (hypermedia))
+ ("rcirc.el"
+ "default, simple IRC client."
+ (comm))
+ ("rcompile.el"
+ "run a compilation on a remote machine"
+ (tools processes))
+ ("rlogin.el"
+ "remote login interface"
+ (unix comm))
+ ("snmp-mode.el"
+ "SNMP & SNMPv2 MIB major mode"
+ (data))
+ ("socks.el"
+ "A Socks v5 Client for Emacs"
+ (comm firewalls))
+ ("telnet.el"
+ "run a telnet session from within an Emacs buffer"
+ (unix comm))
+ ("tls.el"
+ "TLS/SSL support via wrapper around GnuTLS"
+ (comm tls gnutls ssl))
+ ("tramp-ftp.el"
+ "Tramp convenience functions for Ange-FTP"
+ (comm processes))
+ ("tramp-smb.el"
+ "Tramp access functions for SMB servers"
+ (comm processes))
+ ("tramp-util.el"
+ nil
+ (comm extensions processes))
+ ("tramp-uu.el"
+ nil
+ (comm terminals))
+ ("tramp-vc.el"
+ "Version control integration for TRAMP.el"
+ (comm processes))
+ ("tramp.el"
+ nil
+ (comm processes))
+ ("trampver.el"
+ nil
+ (comm processes))
+ ("webjump.el"
+ "programmable Web hotlist"
+ (comm www))
+ ("calc-aent.el"
+ "algebraic entry functions for Calc"
nil)
- ("viper-ex.el"
- "functions implementing the Ex commands for Viper"
+ ("calc-alg.el"
+ "algebraic functions for Calc"
nil)
- ("viper-init.el"
- "some common definitions for Viper"
+ ("calc-arith.el"
+ "arithmetic functions for Calc"
nil)
- ("viper-keym.el"
- "Viper keymaps"
+ ("calc-bin.el"
+ "binary functions for Calc"
nil)
- ("viper-macs.el"
- "functions implementing keyboard macros for Viper"
+ ("calc-comb.el"
+ "combinatoric functions for Calc"
nil)
- ("viper-mous.el"
- "mouse support for Viper"
+ ("calc-cplx.el"
+ "Complex number functions for Calc"
nil)
- ("viper-util.el"
- "Utilities used by viper.el"
+ ("calc-embed.el"
+ "embed Calc in a buffer"
nil)
- ("viper.el"
- "A full-featured Vi emulator for GNU Emacs and XEmacs,"
- (emulations))
- ("ws-mode.el"
- "WordStar emulation mode for GNU Emacs"
- (emulations))
- ("em-alias.el"
- "creation and management of command aliases"
+ ("calc-ext.el"
+ "various extension functions for Calc"
nil)
- ("em-banner.el"
- "sample module that displays a login banner"
+ ("calc-fin.el"
+ "financial functions for Calc"
nil)
- ("em-basic.el"
- "basic shell builtin commands"
+ ("calc-forms.el"
+ "data format conversion functions for Calc"
nil)
- ("em-cmpl.el"
- "completion using the TAB key"
+ ("calc-frac.el"
+ "fraction functions for Calc"
nil)
- ("em-dirs.el"
- "directory navigation commands"
+ ("calc-funcs.el"
+ "well-known functions for Calc"
nil)
- ("em-glob.el"
- "extended file name globbing"
+ ("calc-graph.el"
+ "graph output functions for Calc"
nil)
- ("em-hist.el"
- "history list management"
+ ("calc-help.el"
+ "help display functions for Calc,"
nil)
- ("em-ls.el"
- "implementation of ls in Lisp"
+ ("calc-incom.el"
+ "complex data type input functions for Calc"
nil)
- ("em-pred.el"
- "argument predicates and modifiers (ala zsh)"
+ ("calc-keypd.el"
+ "mouse-capable keypad input for Calc"
nil)
- ("em-prompt.el"
- "command prompts"
+ ("calc-lang.el"
+ "calc language functions"
nil)
- ("em-rebind.el"
- "rebind keys when point is at current input"
+ ("calc-macs.el"
+ "important macros for Calc"
nil)
- ("em-script.el"
- "Eshell script files"
+ ("calc-map.el"
+ "higher-order functions for Calc"
nil)
- ("em-smart.el"
- "smart display of output"
+ ("calc-math.el"
+ "mathematical functions for Calc"
nil)
- ("em-term.el"
- "running visual commands"
+ ("calc-misc.el"
+ "miscellaneous functions for Calc"
nil)
- ("em-unix.el"
- "UNIX command aliases"
+ ("calc-mode.el"
+ "calculator modes for Calc"
nil)
- ("em-xtra.el"
- "extra alias functions"
+ ("calc-mtx.el"
+ "matrix functions for Calc"
nil)
- ("esh-arg.el"
- "argument processing"
+ ("calc-poly.el"
+ "polynomial functions for Calc"
nil)
- ("esh-cmd.el"
- "command invocation"
+ ("calc-prog.el"
+ "user programmability functions for Calc"
nil)
- ("esh-ext.el"
- "commands external to Eshell"
+ ("calc-rewr.el"
+ "rewriting functions for Calc"
nil)
- ("esh-groups.el"
- nil
+ ("calc-rules.el"
+ "rules for simplifying algebraic expressions in Calc"
nil)
- ("esh-io.el"
- "I/O management"
+ ("calc-sel.el"
+ "data selection functions for Calc"
nil)
- ("esh-maint.el"
- "init code for building eshell"
+ ("calc-stat.el"
+ "statistical functions for Calc"
nil)
- ("esh-mode.el"
- "user interface"
+ ("calc-store.el"
+ "value storage functions for Calc"
nil)
- ("esh-module.el"
- "Eshell modules"
- (processes))
- ("esh-opt.el"
- "command options processing"
+ ("calc-stuff.el"
+ "miscellaneous functions for Calc"
nil)
- ("esh-proc.el"
- "process management"
+ ("calc-trail.el"
+ "functions for manipulating the Calc \"trail\""
nil)
- ("esh-test.el"
- "Eshell test suite"
+ ("calc-undo.el"
+ "undo functions for Calc"
nil)
- ("esh-util.el"
- "general utilities"
+ ("calc-units.el"
+ "unit conversion functions for Calc"
+ nil)
+ ("calc-vec.el"
+ "vector functions for Calc"
+ nil)
+ ("calc-yank.el"
+ "kill-ring functionality for Calc"
+ nil)
+ ("calc.el"
+ "the GNU Emacs calculator"
+ (convenience extensions))
+ ("calcalg2.el"
+ "more algebraic functions for Calc"
+ nil)
+ ("calcalg3.el"
+ "more algebraic functions for Calc"
+ nil)
+ ("calccomp.el"
+ "composition functions for Calc"
+ nil)
+ ("calcsel2.el"
+ "selection functions for Calc"
+ nil)
+ ("advice.el"
+ "an overloading mechanism for Emacs Lisp functions"
+ (extensions lisp tools))
+ ("assoc.el"
+ "insert/delete/sort functions on association lists"
+ (extensions))
+ ("authors.el"
+ "utility for maintaining Emacs' AUTHORS file"
+ (maint))
+ ("autoload.el"
+ "maintain autoloads in loaddefs.el"
+ (maint))
+ ("backquote.el"
+ "implement the ` Lisp construct"
+ (extensions internal))
+ ("benchmark.el"
+ "support for benchmarking code"
+ (lisp extensions))
+ ("bindat.el"
+ "binary data structure packing and unpacking."
+ (comm data processes))
+ ("byte-opt.el"
+ "the optimization passes of the emacs-lisp byte compiler"
+ (internal))
+ ("byte-run.el"
+ "byte-compiler support for inlining"
+ (internal))
+ ("bytecomp.el"
+ "compilation of Lisp code into byte code"
+ (lisp))
+ ("checkdoc.el"
+ "check documentation strings for style requirements"
+ (docs maint lisp))
+ ("cl-compat.el"
+ "Common Lisp extensions for GNU Emacs Lisp (compatibility)"
+ (extensions))
+ ("cl-extra.el"
+ "Common Lisp features, part 2"
+ (extensions))
+ ("cl-indent.el"
+ "enhanced lisp-indent mode"
+ (lisp tools))
+ ("cl-loaddefs.el"
+ "automatically extracted autoloads"
+ nil)
+ ("cl-macs.el"
+ "Common Lisp macros"
+ (extensions))
+ ("cl-seq.el"
+ "Common Lisp features, part 3"
+ (extensions))
+ ("cl-specs.el"
+ "Edebug specs for cl.el"
+ (lisp tools maint))
+ ("cl.el"
+ "Common Lisp extensions for Emacs"
+ (extensions))
+ ("copyright.el"
+ "update the copyright notice in current buffer"
+ (maint tools))
+ ("crm.el"
+ "read multiple strings with completion"
+ (completion minibuffer multiple elements))
+ ("cust-print.el"
+ "handles print-level and print-circle"
+ (extensions))
+ ("debug.el"
+ "debuggers and related commands for Emacs"
+ (lisp tools maint))
+ ("derived.el"
+ "allow inheritance of major modes"
+ (extensions))
+ ("disass.el"
+ "disassembler for compiled Emacs Lisp code"
+ (internal))
+ ("easy-mmode.el"
+ "easy definition for major and minor modes"
+ (extensions lisp))
+ ("easymenu.el"
+ "support the easymenu interface for defining a menu"
+ (emulations))
+ ("edebug.el"
+ "a source-level debugger for Emacs Lisp"
+ (lisp tools maint))
+ ("eldoc.el"
+ "show function arglist or variable docstring in echo area"
+ (extensions))
+ ("elint.el"
+ "Lint Emacs Lisp"
+ (lisp))
+ ("elp.el"
+ "Emacs Lisp Profiler"
+ (debugging lisp tools))
+ ("ewoc.el"
+ "utility to maintain a view of a list of objects in a buffer"
+ (extensions lisp))
+ ("find-func.el"
+ "find the definition of the Emacs Lisp function near point"
+ (emacs-lisp functions variables))
+ ("find-gc.el"
+ "detect functions that call the garbage collector"
nil)
- ("esh-var.el"
- "handling of variables"
+ ("float-sup.el"
+ "define some constants useful for floating point numbers."
+ (internal))
+ ("generic.el"
+ "defining simple major modes with comment and font-lock"
+ (generic comment font-lock))
+ ("gulp.el"
+ "ask for updates for Lisp packages"
+ (maintenance))
+ ("helper.el"
+ "utility help package supporting help in electric modes"
+ (help))
+ ("levents.el"
+ "emulate the Lucid event data type and associated functions"
+ (emulations))
+ ("lisp-mnt.el"
+ "utility functions for Emacs Lisp maintainers"
+ (docs))
+ ("lisp-mode.el"
+ "Lisp mode, and its idiosyncratic commands"
+ (lisp languages))
+ ("lisp.el"
+ "Lisp editing commands for Emacs"
+ (lisp languages))
+ ("lmenu.el"
+ "emulate Lucid's menubar support"
+ (emulations obsolete))
+ ("lselect.el"
+ "Lucid interface to X Selections"
+ (emulations))
+ ("lucid.el"
+ "emulate some Lucid Emacs functions"
+ (emulations))
+ ("macroexp.el"
+ "Additional macro-expansion support"
+ (lisp compiler macros))
+ ("map-ynp.el"
+ "general-purpose boolean question-asker"
+ (lisp extensions))
+ ("pp.el"
+ "pretty printer for Emacs Lisp"
+ (lisp))
+ ("re-builder.el"
+ "building Regexps with visual feedback"
+ (matching lisp tools))
+ ("regexp-opt.el"
+ "generate efficient regexps to match strings"
+ (strings regexps extensions))
+ ("regi.el"
+ "REGular expression Interpreting engine"
+ (extensions matching))
+ ("ring.el"
+ "handle rings of items"
+ (extensions))
+ ("rx.el"
+ "sexp notation for regular expressions"
+ (strings regexps extensions))
+ ("shadow.el"
+ "locate Emacs Lisp file shadowings"
+ (lisp))
+ ("sregex.el"
+ "symbolic regular expressions"
+ (extensions))
+ ("syntax.el"
+ "helper functions to find syntactic context"
+ (internal))
+ ("tcover-ses.el"
+ "Example use of `testcover' to test \"SES\""
+ (spreadsheet lisp utility))
+ ("tcover-unsafep.el"
+ "Use testcover to test unsafep's code coverage"
+ (safety lisp utility))
+ ("testcover.el"
+ "Visual code-coverage tool"
+ (lisp utility))
+ ("timer.el"
+ "run a function with args at some time in future"
nil)
- ("eshell.el"
- "the Emacs command shell"
- (processes))
+ ("tq.el"
+ "utility to maintain a transaction queue"
+ (extensions))
+ ("trace.el"
+ "tracing facility for Emacs Lisp functions"
+ (tools lisp))
+ ("unsafep.el"
+ "Determine whether a Lisp form is safe to evaluate"
+ (safety lisp utility))
+ ("warnings.el"
+ "log and display warnings"
+ (internal))
("ccl.el"
"CCL (Code Conversion Language) compiler"
(ccl mule multilingual character set coding-system))
("code-pages.el"
"coding systems for assorted codepages"
(i18n))
- ("codepage.el"
- "MS-DOS/MS-Windows specific coding systems"
- (i18n ms-dos ms-windows codepage))
- ("encoded-kb.el"
- "handler to input multibyte characters encoded somehow"
- nil)
- ("fontset.el"
- "commands for handling fontset"
- (mule multilingual fontset))
- ("isearch-x.el"
- "extended isearch handling commands"
- (multilingual isearch))
- ("iso-ascii.el"
- "set up char tables for ISO 8859/1 on ASCII terminals"
- (i18n))
- ("iso-cvt.el"
- "translate ISO 8859-1 from/to various encodings"
- (tex iso latin i18n))
- ("iso-transl.el"
- "keyboard input definitions for ISO 8859-1"
- (i18n))
- ("ja-dic-cnv.el"
- "convert a Japanese dictionary (SKK-JISYO.L) to Emacs Lisp"
- (mule multilingual japanese))
- ("ja-dic-utl.el"
- "utilities for handling Japanese dictionary (SKK-JISYO.L)"
- (mule multilingual japanese))
- ("kinsoku.el"
- "`Kinsoku' processing funcs"
- (mule kinsoku))
- ("kkc.el"
- "Kana Kanji converter"
- (mule multilingual japanese))
- ("latexenc.el"
- "guess correct coding system in LaTeX files"
- (mule coding system latex))
- ("latin-1.el"
- "set up case-conversion and syntax tables for ISO Latin-1"
- (i18n))
- ("latin-2.el"
- "set up case-conversion and syntax tables for ISO Latin-2"
- (i18n))
- ("latin-3.el"
- "set up case-conversion and syntax tables for ISO Latin-3"
- (i18n))
- ("latin-4.el"
- "set up case-conversion and syntax tables for ISO Latin-4"
- (i18n))
- ("latin-5.el"
- "set up case-conversion and syntax tables for ISO latin-5"
- (i18n))
- ("latin-8.el"
- "set up case-conversion and syntax tables for ISO Latin-8"
- (i18n))
- ("latin-9.el"
- "set up case-conversion and syntax tables for ISO Latin-9"
- (i18n))
- ("latin1-disp.el"
- "display tables for other ISO 8859 on Latin-1 terminals"
- (i18n))
- ("mule-cmds.el"
- "commands for multilingual environment"
- (mule multilingual))
- ("mule-conf.el"
- "configure multilingual environment"
- (mule multilingual character set coding system))
- ("mule-diag.el"
- "show diagnosis of multilingual environment (Mule)"
- (multilingual charset coding system fontset diagnosis i18n))
- ("mule-util.el"
- "utility functions for mulitilingual environment (mule)"
- (mule multilingual))
- ("mule.el"
- "basic commands for mulitilingual environment"
- (mule multilingual character set coding system))
- ("ogonek.el"
- "change the encoding of Polish diacritics"
- (i18n))
- ("quail.el"
- "provides simple input method for multilingual text"
- (mule multilingual input method i18n))
- ("subst-big5.el"
- "Unicode/GB2312 translation"
- (i18n))
- ("subst-gb2312.el"
- "Unicode/GB2312 translation"
- (i18n))
- ("subst-jis.el"
- "Unicode/JISX translation"
- (i18n))
- ("subst-ksc.el"
- "Unicode/KSC-5601 translation"
- (i18n))
- ("titdic-cnv.el"
- "convert cxterm dictionary (TIT format) to Quail package"
- (quail tit cxterm))
- ("ucs-tables.el"
- "translation to, from and via Unicode"
- (i18n))
- ("utf-16.el"
- "UTF-16 encoding/decoding"
- (unicode utf-16 i18n))
- ("utf-7.el"
- "utf-7 coding system"
- (i18n mail))
- ("utf-8.el"
- "UTF-8 decoding/encoding support"
- (multilingual unicode utf-8 i18n))
- ("china-util.el"
- "utilities for Chinese"
- (mule multilingual chinese))
- ("chinese.el"
- "support for Chinese"
- (multilingual chinese))
- ("cyril-util.el"
- "utilities for Cyrillic scripts"
- (mule multilingual cyrillic))
- ("cyrillic.el"
- "support for Cyrillic"
- (multilingual cyrillic i18n))
- ("czech.el"
- "support for Czech"
- (multilingual czech))
- ("devan-util.el"
- "Support for composing Devanagari characters"
- (multilingual devanagari))
- ("devanagari.el"
- "Support for Devanagari"
- (multilingual indian devanagari))
- ("english.el"
- "support for English"
- (multibyte character character set syntax category))
- ("ethio-util.el"
- "utilities for Ethiopic"
- (mule multilingual ethiopic))
- ("ethiopic.el"
- "support for Ethiopic"
- (multilingual ethiopic))
- ("european.el"
- "support for European languages"
- (multilingual european))
- ("georgian.el"
- "language support for Georgian"
+ ("codepage.el"
+ "MS-DOS/MS-Windows specific coding systems"
+ (i18n ms-dos ms-windows codepage))
+ ("encoded-kb.el"
+ "handler to input multibyte characters encoded somehow"
+ nil)
+ ("fontset.el"
+ "commands for handling fontset"
+ (mule multilingual fontset))
+ ("isearch-x.el"
+ "extended isearch handling commands"
+ (multilingual isearch))
+ ("iso-ascii.el"
+ "set up char tables for ISO 8859/1 on ASCII terminals"
(i18n))
- ("greek.el"
- "support for Greek"
- (multilingual greek))
- ("hebrew.el"
- "support for Hebrew"
- (multilingual hebrew))
- ("ind-util.el"
- "Transliteration and Misc. Tools for Indian Languages"
- (multilingual indian devanagari))
- ("indian.el"
- "Indian languages support"
- (multilingual i18n indian))
- ("japan-util.el"
- "utilities for Japanese"
+ ("iso-cvt.el"
+ "translate ISO 8859-1 from/to various encodings"
+ (tex iso latin i18n))
+ ("iso-transl.el"
+ "keyboard input definitions for ISO 8859-1"
+ (i18n))
+ ("ja-dic-cnv.el"
+ "convert a Japanese dictionary (SKK-JISYO.L) to Emacs Lisp"
(mule multilingual japanese))
- ("japanese.el"
- "support for Japanese"
- (multilingual japanese))
- ("kannada.el"
- "Support for Kannada"
- (multilingual indian kannada))
- ("knd-util.el"
- "Support for composing Kannada characters"
- (multilingual kannada))
- ("korea-util.el"
- "utilities for Korean"
- (mule multilingual korean))
- ("korean.el"
- "support for Korean"
- (multilingual korean))
- ("lao-util.el"
- "utilities for Lao"
- (multilingual lao))
- ("lao.el"
- "support for Lao"
- (multilingual lao))
- ("malayalam.el"
- "Support for Malayalam"
- (multilingual indian malayalam))
- ("misc-lang.el"
- "support for miscellaneous languages (characters)"
- (multilingual character set coding system))
- ("mlm-util.el"
- "support for composing malayalam characters"
- (multilingual malayalam))
- ("romanian.el"
- "support for Romanian"
- (multilingual romanian))
- ("slovak.el"
- "support for Slovak"
- (multilingual slovak))
- ("tamil.el"
- "Support for Tamil"
- (multilingual indian tamil))
- ("thai-util.el"
- "utilities for Thai"
- (mule multilingual thai))
- ("thai-word.el"
- "find Thai word boundaries"
- (thai word break emacs))
- ("thai.el"
- "support for Thai"
- (multilingual thai))
- ("tibet-util.el"
- "utilities for Tibetan"
- (multilingual tibetan))
- ("tibetan.el"
- "support for Tibetan language"
- (multilingual tibetan))
- ("tml-util.el"
- "support for composing tamil characters"
- (multilingual indian tamil))
- ("utf-8-lang.el"
- "generic UTF-8 language environment"
+ ("ja-dic-utl.el"
+ "utilities for handling Japanese dictionary (SKK-JISYO.L)"
+ (mule multilingual japanese))
+ ("kinsoku.el"
+ "`Kinsoku' processing funcs"
+ (mule kinsoku))
+ ("kkc.el"
+ "Kana Kanji converter"
+ (mule multilingual japanese))
+ ("latexenc.el"
+ "guess correct coding system in LaTeX files"
+ (mule coding system latex))
+ ("latin-1.el"
+ "set up case-conversion and syntax tables for ISO Latin-1"
(i18n))
- ("viet-util.el"
- "utilities for Vietnamese"
- (mule multilingual vietnamese))
- ("vietnamese.el"
- "support for Vietnamese"
- (multilingual vietnamese))
- ("mh-acros.el"
- "macros used in MH-E"
- (mail))
- ("mh-alias.el"
- "MH-E mail alias completion and expansion"
- (mail))
- ("mh-buffers.el"
- "MH-E buffer constants and utilities"
- (mail))
- ("mh-comp.el"
- "MH-E functions for composing and sending messages"
- (mail))
- ("mh-compat.el"
- "make MH-E compatibile with various versions of Emacs"
- (mail))
- ("mh-e.el"
- "GNU Emacs interface to the MH mail system"
- (mail))
- ("mh-folder.el"
- "MH-Folder mode"
- (mail))
- ("mh-funcs.el"
- "MH-E functions not everyone will use right away"
- (mail))
- ("mh-gnus.el"
- "make MH-E compatible with various versions of Gnus"
- (mail))
- ("mh-identity.el"
- "multiple identify support for MH-E"
- (mail))
- ("mh-inc.el"
- "MH-E \"inc\" and separate mail spool handling"
- (mail))
- ("mh-junk.el"
- "MH-E interface to anti-spam measures"
- (mail spam))
- ("mh-letter.el"
- "MH-Letter mode"
- (mail))
- ("mh-limit.el"
- "MH-E display limits"
- (mail))
- ("mh-loaddefs.el"
- "automatically extracted autoloads"
- (mail))
- ("mh-mime.el"
- "MH-E MIME support"
- (mail))
- ("mh-print.el"
- "MH-E printing support"
- (mail))
- ("mh-scan.el"
- "MH-E scan line constants and utilities"
- (mail))
- ("mh-search.el"
- "MH-Search mode"
- (mail))
- ("mh-seq.el"
- "MH-E sequences support"
- (mail))
- ("mh-show.el"
- "MH-Show mode"
- (mail))
- ("mh-speed.el"
- "MH-E speedbar support"
- (mail))
- ("mh-thread.el"
- "MH-E threading support"
- (mail))
- ("mh-tool-bar.el"
- "MH-E tool bar support"
- (mail))
- ("mh-utils.el"
- "MH-E general utilities"
- (mail))
- ("mh-xface.el"
- "MH-E X-Face and Face header field display"
- (mail))
- ("ange-ftp.el"
- "transparent FTP support for GNU Emacs"
- (comm))
- ("browse-url.el"
- "pass a URL to a WWW browser"
- (hypertext hypermedia mouse))
- ("eudc-bob.el"
- "Binary Objects Support for EUDC"
- (comm))
- ("eudc-export.el"
- "functions to export EUDC query results"
- (comm))
- ("eudc-hotlist.el"
- "hotlist management for EUDC"
- (comm))
- ("eudc-vars.el"
- "Emacs Unified Directory Client"
- (comm))
- ("eudc.el"
- "Emacs Unified Directory Client"
- (comm))
- ("eudcb-bbdb.el"
- "Emacs Unified Directory Client - BBDB Backend"
- (comm))
- ("eudcb-ldap.el"
- "Emacs Unified Directory Client - LDAP Backend"
- (comm))
- ("eudcb-mab.el"
- "Emacs Unified Directory Client - AddressBook backend"
- (comm))
- ("eudcb-ph.el"
- "Emacs Unified Directory Client - CCSO PH/QI Backend"
- (comm))
- ("goto-addr.el"
- "click to browse URL or to send to e-mail address"
- (mh-e www mouse mail))
- ("ldap.el"
- "client interface to LDAP for Emacs"
- (comm))
- ("net-utils.el"
- "network functions"
- (network comm))
- ("netrc.el"
- ".netrc parsing functionality"
+ ("latin-2.el"
+ "set up case-conversion and syntax tables for ISO Latin-2"
+ (i18n))
+ ("latin-3.el"
+ "set up case-conversion and syntax tables for ISO Latin-3"
+ (i18n))
+ ("latin-4.el"
+ "set up case-conversion and syntax tables for ISO Latin-4"
+ (i18n))
+ ("latin-5.el"
+ "set up case-conversion and syntax tables for ISO latin-5"
+ (i18n))
+ ("latin-8.el"
+ "set up case-conversion and syntax tables for ISO Latin-8"
+ (i18n))
+ ("latin-9.el"
+ "set up case-conversion and syntax tables for ISO Latin-9"
+ (i18n))
+ ("latin1-disp.el"
+ "display tables for other ISO 8859 on Latin-1 terminals"
+ (i18n))
+ ("mule-cmds.el"
+ "commands for multilingual environment"
+ (mule multilingual))
+ ("mule-conf.el"
+ "configure multilingual environment"
+ (mule multilingual character set coding system))
+ ("mule-diag.el"
+ "show diagnosis of multilingual environment (Mule)"
+ (multilingual charset coding system fontset diagnosis i18n))
+ ("mule-util.el"
+ "utility functions for mulitilingual environment (mule)"
+ (mule multilingual))
+ ("mule.el"
+ "basic commands for mulitilingual environment"
+ (mule multilingual character set coding system))
+ ("ogonek.el"
+ "change the encoding of Polish diacritics"
+ (i18n))
+ ("quail.el"
+ "provides simple input method for multilingual text"
+ (mule multilingual input method i18n))
+ ("subst-big5.el"
+ "Unicode/GB2312 translation"
+ (i18n))
+ ("subst-gb2312.el"
+ "Unicode/GB2312 translation"
+ (i18n))
+ ("subst-jis.el"
+ "Unicode/JISX translation"
+ (i18n))
+ ("subst-ksc.el"
+ "Unicode/KSC-5601 translation"
+ (i18n))
+ ("titdic-cnv.el"
+ "convert cxterm dictionary (TIT format) to Quail package"
+ (quail tit cxterm))
+ ("ucs-tables.el"
+ "translation to, from and via Unicode"
+ (i18n))
+ ("utf-16.el"
+ "UTF-16 encoding/decoding"
+ (unicode utf-16 i18n))
+ ("utf-7.el"
+ "utf-7 coding system"
+ (i18n mail))
+ ("utf-8.el"
+ "UTF-8 decoding/encoding support"
+ (multilingual unicode utf-8 i18n))
+ ("binhex.el"
+ "elisp native binhex decode"
+ (binhex news))
+ ("canlock.el"
+ "functions for Cancel-Lock feature"
+ (news cancel-lock hmac sha1 rfc2104))
+ ("compface.el"
+ "functions for converting X-Face headers"
(news))
- ("newsticker.el"
- "A Newsticker for Emacs."
- (news rss atom))
- ("quickurl.el"
- "insert an URL based on text at point in buffer"
- (hypermedia))
- ("rcirc.el"
- "default, simple IRC client."
- (comm))
- ("rcompile.el"
- "run a compilation on a remote machine"
- (tools processes))
- ("rlogin.el"
- "remote login interface"
- (unix comm))
- ("snmp-mode.el"
- "SNMP & SNMPv2 MIB major mode"
- (data))
- ("socks.el"
- "A Socks v5 Client for Emacs"
- (comm firewalls))
- ("telnet.el"
- "run a telnet session from within an Emacs buffer"
- (unix comm))
- ("tls.el"
- "TLS/SSL support via wrapper around GnuTLS"
- (comm tls gnutls ssl))
- ("tramp-ftp.el"
- "Tramp convenience functions for Ange-FTP"
- (comm processes))
- ("tramp-smb.el"
- "Tramp access functions for SMB servers"
- (comm processes))
- ("tramp-util.el"
- nil
- (comm extensions processes))
- ("tramp-uu.el"
- nil
- (comm terminals))
- ("tramp-vc.el"
- "Version control integration for TRAMP.el"
- (comm processes))
- ("tramp.el"
- nil
- (comm processes))
- ("trampver.el"
- nil
- (comm processes))
- ("webjump.el"
- "programmable Web hotlist"
- (comm www))
- ("5x5.el"
- "simple little puzzle game"
- (games puzzles))
- ("animate.el"
- "make text dance"
- (games))
- ("blackbox.el"
- "blackbox game in Emacs Lisp"
- (games))
- ("bruce.el"
- "bruce phrase utility for overloading the Communications"
- (games))
- ("cookie1.el"
- "retrieve random phrases from fortune cookie files"
- (games extensions))
- ("decipher.el"
- "cryptanalyze monoalphabetic substitution ciphers"
- (games))
- ("dissociate.el"
- "scramble text amusingly for Emacs"
- (games))
- ("doctor.el"
- "psychological help for frustrated users"
- (games))
- ("dunnet.el"
- "text adventure for Emacs"
- (games))
- ("fortune.el"
- "use fortune to create signatures"
- (games utils mail))
- ("gamegrid.el"
- "library for implementing grid-based games on Emacs"
- (games))
- ("gametree.el"
- "manage game analysis trees in Emacs"
- (games))
- ("gomoku.el"
- "Gomoku game between you and Emacs"
- (games))
- ("handwrite.el"
- "turns your emacs buffer into a handwritten document"
- (wp print postscript cursive writing))
- ("hanoi.el"
- "towers of hanoi in Emacs"
- (games))
- ("landmark.el"
- "neural-network robot that learns landmarks"
- (gomoku neural network adaptive search chemotaxis))
- ("life.el"
- "John Horton Conway's `Life' game for GNU Emacs"
- (games))
- ("meese.el"
- "protect the impressionable young minds of America"
- (games))
- ("morse.el"
- "convert text to morse code and back"
- (games))
- ("mpuz.el"
- "multiplication puzzle for GNU Emacs"
- (games))
- ("pong.el"
- "classical implementation of pong"
- (games))
- ("snake.el"
- "implementation of Snake for Emacs"
- (games))
- ("solitaire.el"
- "game of solitaire in Emacs Lisp"
- (games))
- ("spook.el"
- "spook phrase utility for overloading the NSA line eater"
- (games))
- ("studly.el"
- "StudlyCaps (tm)(r)(c)(xxx)"
- (games))
- ("tetris.el"
- "implementation of Tetris for Emacs"
- (games))
- ("yow.el"
- "quote random zippyisms"
- (games))
- ("zone.el"
- "idle display hacks"
- (games))
- ("ada-mode.el"
- "major-mode for editing Ada sources"
- (languages ada))
- ("ada-prj.el"
- "GUI editing of project files for the ada-mode"
- (languages ada project file))
- ("ada-stmt.el"
- "an extension to Ada mode for inserting statement templates"
- (languages ada))
- ("ada-xref.el"
- "for lookup and completion in Ada mode"
- (languages ada xref))
- ("antlr-mode.el"
- "major mode for ANTLR grammar files"
- (languages antlr code generator))
- ("asm-mode.el"
- "mode for editing assembler code"
- (tools languages))
- ("autoconf.el"
- "mode for editing Autoconf configure.in files"
- (languages))
- ("cc-align.el"
- "custom indentation functions for CC Mode"
- (c languages oop))
- ("cc-awk.el"
- "AWK specific code within cc-mode."
- (awk cc-mode unix languages))
- ("cc-bytecomp.el"
- "compile time setup for proper compilation"
- (c languages oop))
- ("cc-cmds.el"
- "user level commands for CC Mode"
- (c languages oop))
- ("cc-compat.el"
- "cc-mode compatibility with c-mode.el confusion"
- (c languages oop))
- ("cc-defs.el"
- "compile time definitions for CC Mode"
- (c languages oop))
- ("cc-engine.el"
- "core syntax guessing engine for CC mode"
- (c languages oop))
- ("cc-fonts.el"
- "font lock support for CC Mode"
- (c languages oop))
- ("cc-langs.el"
- "language specific settings for CC Mode"
- (c languages oop))
- ("cc-menus.el"
- "imenu support for CC Mode"
- (c languages oop))
- ("cc-mode.el"
- "major mode for editing C and similar languages"
- (c languages oop))
- ("cc-styles.el"
- "support for styles in CC Mode"
- (c languages oop))
- ("cc-subword.el"
- "Handling capitalized subwords in a nomenclature"
+ ("deuglify.el"
+ "deuglify broken Outlook (Express) articles"
+ (mail news))
+ ("dig.el"
+ "Domain Name System dig interface"
+ (dns bind dig))
+ ("dns.el"
+ "Domain Name Service lookups"
+ (network))
+ ("earcon.el"
+ "Sound effects for messages"
nil)
- ("cc-vars.el"
- "user customization variables for CC Mode"
- (c languages oop))
- ("cfengine.el"
- "mode for editing Cfengine files"
- (languages))
- ("cmacexp.el"
- "expand C macros in a region"
- (c))
- ("compile.el"
- "run compiler as inferior of Emacs, parse error messages"
- (tools processes))
- ("cperl-mode.el"
- "Perl code editing commands for Emacs"
- (languages perl))
- ("cpp.el"
- "highlight or hide text according to cpp conditionals"
- (c faces tools))
- ("cwarn.el"
- "highlight suspicious C and C++ constructions"
- (c languages faces))
- ("dcl-mode.el"
- "major mode for editing DCL command files"
- (dcl editing major-mode languages))
- ("delphi.el"
- "major mode for editing Delphi source (Object Pascal) in Emacs"
- (languages))
- ("ebnf-abn.el"
- "parser for ABNF (Augmented BNF)"
- (wp ebnf postscript))
- ("ebnf-bnf.el"
- "parser for EBNF"
- (wp ebnf postscript))
- ("ebnf-dtd.el"
- "parser for DTD (Data Type Description for XML)"
- (wp ebnf postscript))
- ("ebnf-ebx.el"
- "parser for EBNF used to specify XML (EBNFX)"
- (wp ebnf postscript))
- ("ebnf-iso.el"
- "parser for ISO EBNF"
- (wp ebnf postscript))
- ("ebnf-otz.el"
- "syntactic chart OpTimiZer"
- (wp ebnf postscript))
- ("ebnf-yac.el"
- "parser for Yacc/Bison"
- (wp ebnf postscript))
- ("ebnf2ps.el"
- "translate an EBNF to a syntactic chart on PostScript"
- (wp ebnf postscript))
- ("ebrowse.el"
- "Emacs C++ class browser & tags facility"
- (c++ tags tools))
- ("etags.el"
- "etags facility for Emacs"
- (tools))
- ("executable.el"
- "base functionality for executable interpreter scripts"
- (languages unix))
- ("f90.el"
- "Fortran-90 mode (free format)"
- (fortran f90 languages))
- ("flymake.el"
- "a universal on-the-fly syntax checker"
- (c languages tools))
- ("fortran.el"
- "Fortran mode for GNU Emacs"
- (fortran languages))
- ("gdb-ui.el"
- "User Interface for running GDB"
- (unix tools))
- ("glasses.el"
- "make cantReadThis readable"
+ ("flow-fill.el"
+ "interpret RFC2646 \"flowed\" text"
+ (mail))
+ ("format-spec.el"
+ "functions for formatting arbitrary formatting strings"
(tools))
- ("grep.el"
- "run Grep as inferior of Emacs, parse match messages"
- (tools processes))
- ("gud.el"
- "Grand Unified Debugger mode for running GDB and other debuggers"
- (unix tools))
- ("hideif.el"
- "hides selected code within ifdef"
- (c outlines))
- ("hideshow.el"
- "minor mode cmds to selectively display code/comment blocks"
- (c c++ java lisp tools editing comments blocks hiding outlines))
- ("icon.el"
- "mode for editing Icon code"
- (languages))
- ("idlw-complete-structtag.el"
- "Completion of structure tags."
- (languages))
- ("idlw-help.el"
- "HTML Help code for IDLWAVE"
+ ("gmm-utils.el"
+ "Utility functions for Gnus, Message and MML"
+ (news))
+ ("gnus-agent.el"
+ "unplugged support for Gnus"
+ nil)
+ ("gnus-art.el"
+ "article mode commands for Gnus"
+ (news))
+ ("gnus-async.el"
+ "asynchronous support for Gnus"
+ (news))
+ ("gnus-audio.el"
+ "Sound effects for Gnus"
+ (news mail multimedia))
+ ("gnus-bcklg.el"
+ "backlog functions for Gnus"
+ (news))
+ ("gnus-cache.el"
+ "cache interface for Gnus"
+ (news))
+ ("gnus-cite.el"
+ "parse citations in articles for Gnus"
+ nil)
+ ("gnus-cus.el"
+ "customization commands for Gnus"
+ (news))
+ ("gnus-delay.el"
+ "Delayed posting of articles"
+ (mail news extensions))
+ ("gnus-demon.el"
+ "daemonic Gnus behaviour"
+ (news))
+ ("gnus-diary.el"
+ "Wrapper around the NNDiary Gnus back end"
+ (calendar mail news))
+ ("gnus-dired.el"
+ "utility functions where gnus and dired meet"
+ (mail news extensions))
+ ("gnus-draft.el"
+ "draft message support for Gnus"
+ (news))
+ ("gnus-dup.el"
+ "suppression of duplicate articles in Gnus"
+ (news))
+ ("gnus-eform.el"
+ "a mode for editing forms for Gnus"
+ (news))
+ ("gnus-ems.el"
+ "functions for making Gnus work under different Emacsen"
+ (news))
+ ("gnus-fun.el"
+ "various frivolous extension functions to Gnus"
+ (news))
+ ("gnus-gl.el"
+ "an interface to GroupLens for Gnus"
+ (news score))
+ ("gnus-group.el"
+ "group mode commands for Gnus"
+ (news))
+ ("gnus-int.el"
+ "backend interface functions for Gnus"
+ (news))
+ ("gnus-kill.el"
+ "kill commands for Gnus"
+ (news))
+ ("gnus-logic.el"
+ "advanced scoring code for Gnus"
+ (news))
+ ("gnus-mh.el"
+ "mh-e interface for Gnus"
+ (news))
+ ("gnus-ml.el"
+ "Mailing list minor mode for Gnus"
+ (news mail))
+ ("gnus-mlspl.el"
+ "a group params-based mail splitting mechanism"
+ (news mail))
+ ("gnus-move.el"
+ "commands for moving Gnus from one server to another"
+ (news))
+ ("gnus-msg.el"
+ "mail and post interface for Gnus"
+ (news))
+ ("gnus-nocem.el"
+ "NoCeM pseudo-cancellation treatment"
+ (news))
+ ("gnus-picon.el"
+ "displaying pretty icons in Gnus"
+ (news xpm annotation glyph faces))
+ ("gnus-range.el"
+ "range and sequence functions for Gnus"
+ (news))
+ ("gnus-registry.el"
+ "article registry for Gnus"
+ (news registry))
+ ("gnus-salt.el"
+ "alternate summary mode interfaces for Gnus"
+ (news))
+ ("gnus-score.el"
+ "scoring code for Gnus"
+ (news))
+ ("gnus-setup.el"
+ "Initialization & Setup for Gnus 5"
+ (news))
+ ("gnus-sieve.el"
+ "Utilities to manage sieve scripts for Gnus"
+ nil)
+ ("gnus-soup.el"
+ "SOUP packet writing support for Gnus"
+ (news mail))
+ ("gnus-spec.el"
+ "format spec functions for Gnus"
+ (news))
+ ("gnus-srvr.el"
+ "virtual server support for Gnus"
+ (news))
+ ("gnus-start.el"
+ "startup functions for Gnus"
+ (news))
+ ("gnus-sum.el"
+ "summary mode commands for Gnus"
+ (news))
+ ("gnus-topic.el"
+ "a folding minor mode for Gnus group buffers"
+ (news))
+ ("gnus-undo.el"
+ "minor mode for undoing in Gnus"
+ (news))
+ ("gnus-util.el"
+ "utility functions for Gnus"
+ (news))
+ ("gnus-uu.el"
+ "extract (uu)encoded files in Gnus"
+ nil)
+ ("gnus-vm.el"
+ "vm interface for Gnus"
+ (news mail))
+ ("gnus-win.el"
+ "window configuration functions for Gnus"
+ (news))
+ ("gnus.el"
+ "a newsreader for GNU Emacs"
+ (news mail))
+ ("hex-util.el"
+ "Functions to encode/decode hexadecimal string."
+ (data))
+ ("html2text.el"
+ "a simple html to plain text converter"
+ nil)
+ ("ietf-drums.el"
+ "Functions for parsing RFC822bis headers"
nil)
- ("idlw-shell.el"
- "run IDL as an inferior process of Emacs."
- (processes))
- ("idlw-toolbar.el"
- "a debugging toolbar for IDLWAVE"
- (processes))
- ("idlwave.el"
- "IDL editing mode for GNU Emacs"
- (languages))
- ("inf-lisp.el"
- "an inferior-lisp mode"
- (processes lisp))
- ("ld-script.el"
- "GNU linker script editing mode for Emacs"
- (languages faces))
- ("m4-mode.el"
- "m4 code editing commands for Emacs"
- (languages faces))
- ("make-mode.el"
- "makefile editing commands for Emacs"
- (unix tools))
- ("mantemp.el"
- "create manual template instantiations from g++ 2.7.2 output"
- (g++ templates))
- ("meta-mode.el"
- "major mode for editing Metafont or MetaPost sources"
- (metafont metapost tex languages))
- ("mixal-mode.el"
- "Major mode for the mix asm language."
- (knuth mix mixal asm mixvm "the art of computer programming"))
- ("modula2.el"
- "Modula-2 editing support package"
- (languages))
- ("octave-hlp.el"
- "getting help on Octave symbols using info"
- (languages))
- ("octave-inf.el"
- "running Octave as an inferior Emacs process"
- (languages))
- ("octave-mod.el"
- "editing Octave source files under Emacs"
- (languages))
- ("pascal.el"
- "major mode for editing pascal source in Emacs"
- (languages))
- ("perl-mode.el"
- "Perl code editing commands for GNU Emacs"
- (languages))
- ("prolog.el"
- "major mode for editing and running Prolog under Emacs"
- (languages))
- ("ps-mode.el"
- "PostScript mode for GNU Emacs"
- (postscript languages))
- ("python.el"
- "silly walks for Python"
- (languages))
- ("scheme.el"
- "Scheme (and DSSSL) editing mode"
- (languages lisp))
- ("sh-script.el"
- "shell-script editing commands for Emacs"
- (languages unix))
- ("simula.el"
- "SIMULA 87 code editing commands for Emacs"
- (languages))
- ("sql.el"
- "specialized comint.el for SQL interpreters"
- (comm languages processes))
- ("tcl.el"
- "Tcl code editing commands for Emacs"
- (languages tcl modes))
- ("vera-mode.el"
- "major mode for editing Vera files."
- (languages vera))
- ("verilog-mode.el"
- "major mode for editing verilog source in Emacs"
- (languages))
- ("vhdl-mode.el"
- "major mode for editing VHDL code"
- (languages vhdl))
- ("which-func.el"
- "print current function in mode line"
- (mode-line imenu tools))
- ("xscheme.el"
- "run MIT Scheme under Emacs"
- (languages lisp))
- ("artist.el"
- "draw ascii graphics with your mouse"
- (mouse))
- ("bib-mode.el"
- "major mode for editing bib files"
- (bib))
- ("bibtex-style.el"
- "Major mode for BibTeX Style files"
+ ("imap.el"
+ "imap library"
+ (mail))
+ ("legacy-gnus-agent.el"
+ "Legacy unplugged support for Gnus"
+ (news))
+ ("mail-parse.el"
+ "Interface functions for parsing mail"
nil)
- ("bibtex.el"
- "BibTeX mode for GNU Emacs"
- (bibtex latex tex))
- ("conf-mode.el"
- "Simple major mode for editing conf/ini/properties files"
- (conf ini windows java))
- ("css-mode.el"
- "Major mode to edit CSS files"
- (hypermedia))
- ("dns-mode.el"
- "a mode for viewing/editing Domain Name System master files"
- (dns master zone file soa))
- ("enriched.el"
- "read and save files in text/enriched format"
- (wp faces))
- ("fill.el"
- "fill commands for Emacs"
- (wp))
- ("flyspell.el"
- "on-the-fly spell checker"
- (convenience))
- ("ispell.el"
- "interface to International Ispell Versions 3.1 and 3.2"
- (unix wp))
- ("makeinfo.el"
- "run makeinfo conveniently"
- (docs convenience))
- ("nroff-mode.el"
- "GNU Emacs major mode for editing nroff source"
- (wp))
- ("org.el"
- "Outline-based notes management and organize"
- (outlines hypermedia calendar wp))
- ("page-ext.el"
- "extended page handling commands"
- (wp data))
- ("page.el"
- "page motion commands for Emacs"
- (wp convenience))
- ("paragraphs.el"
- "paragraph and sentence parsing"
- (wp))
- ("picture.el"
- "\"Picture mode\" -- editing using quarter-plane screen model"
- (convenience wp))
- ("po.el"
- "basic support of PO translation files"
- (i18n files))
- ("refbib.el"
- "convert refer-style references to ones usable by Latex bib"
- (bib tex))
- ("refer.el"
- "look up references in bibliography files"
- (bib))
- ("refill.el"
- "`auto-fill' by refilling paragraphs on changes"
- (wp))
- ("reftex-auc.el"
- "RefTeX's interface to AUCTeX"
+ ("mail-prsvr.el"
+ "Interface variables for parsing mail"
nil)
- ("reftex-cite.el"
- "creating citations with RefTeX"
+ ("mail-source.el"
+ "functions for fetching mail"
+ (news mail))
+ ("mailcap.el"
+ "MIME media types configuration"
+ (news mail multimedia))
+ ("message.el"
+ "composing mail and news messages"
+ (mail news))
+ ("messcompat.el"
+ "making message mode compatible with mail mode"
+ (mail news))
+ ("mm-bodies.el"
+ "Functions for decoding MIME things"
nil)
- ("reftex-dcr.el"
- "viewing cross references and citations with RefTeX"
+ ("mm-decode.el"
+ "Functions for decoding MIME things"
+ nil)
+ ("mm-encode.el"
+ "Functions for encoding MIME things"
+ nil)
+ ("mm-extern.el"
+ "showing message/external-body"
+ (message external-body))
+ ("mm-partial.el"
+ "showing message/partial"
+ (message partial))
+ ("mm-url.el"
+ "a wrapper of url functions/commands for Gnus"
+ nil)
+ ("mm-util.el"
+ "Utility functions for Mule and low level things"
+ nil)
+ ("mm-uu.el"
+ "Return uu stuff as mm handles"
+ (postscript uudecode binhex shar forward gnatsweb pgp))
+ ("mm-view.el"
+ "functions for viewing MIME objects"
+ nil)
+ ("mml-sec.el"
+ "A package with security functions for MML documents"
+ nil)
+ ("mml-smime.el"
+ "S/MIME support for MML"
+ (gnus mime s/mime mml))
+ ("mml.el"
+ "A package for parsing and validating MML documents"
+ nil)
+ ("mml1991.el"
+ "Old PGP message format (RFC 1991) support for MML"
+ nil)
+ ("mml2015.el"
+ "MIME Security with Pretty Good Privacy (PGP)"
+ (pgp mime mml))
+ ("nnagent.el"
+ "offline backend for Gnus"
+ (news mail))
+ ("nnbabyl.el"
+ "rmail mbox access for Gnus"
+ (news mail))
+ ("nndb.el"
+ "nndb access for Gnus"
+ (news))
+ ("nndiary.el"
+ "A diary back end for Gnus"
+ (calendar mail news))
+ ("nndir.el"
+ "single directory newsgroup access for Gnus"
+ (news))
+ ("nndoc.el"
+ "single file access for Gnus"
+ (news))
+ ("nndraft.el"
+ "draft article access for Gnus"
+ (news))
+ ("nneething.el"
+ "arbitrary file access for Gnus"
+ (news mail))
+ ("nnfolder.el"
+ "mail folder access for Gnus"
+ (mail))
+ ("nngateway.el"
+ "posting news via mail gateways"
+ (news mail))
+ ("nnheader.el"
+ "header access macros for Gnus and its backends"
+ (news))
+ ("nnimap.el"
+ "imap backend for Gnus"
+ (mail))
+ ("nnkiboze.el"
+ "select virtual news access for Gnus"
+ (news))
+ ("nnlistserv.el"
+ "retrieving articles via web mailing list archives"
+ (news mail))
+ ("nnmail.el"
+ "mail support functions for the Gnus mail backends"
+ (news mail))
+ ("nnmaildir.el"
+ "maildir backend for Gnus"
nil)
- ("reftex-global.el"
- "operations on entire documents with RefTeX"
+ ("nnmbox.el"
+ "mail mbox access for Gnus"
+ (news mail))
+ ("nnmh.el"
+ "mhspool access for Gnus"
+ (news mail))
+ ("nnml.el"
+ "mail spool access for Gnus"
+ (news mail))
+ ("nnnil.el"
+ "empty backend for Gnus"
nil)
- ("reftex-index.el"
- "index support with RefTeX"
+ ("nnoo.el"
+ "OO Gnus Backends"
+ (news))
+ ("nnrss.el"
+ "interfacing with RSS"
+ (rss))
+ ("nnslashdot.el"
+ "interfacing with Slashdot"
+ (news))
+ ("nnsoup.el"
+ "SOUP access for Gnus"
+ (news mail))
+ ("nnspool.el"
+ "spool access for GNU Emacs"
+ (news))
+ ("nntp.el"
+ "nntp access for Gnus"
+ (news))
+ ("nnultimate.el"
+ "interfacing with the Ultimate Bulletin Board system"
+ (news))
+ ("nnvirtual.el"
+ "virtual newsgroups access for Gnus"
+ (news))
+ ("nnwarchive.el"
+ "interfacing with web archives"
+ (news egroups mail-archive))
+ ("nnweb.el"
+ "retrieving articles via web search engines"
+ (news))
+ ("nnwfm.el"
+ "interfacing with a web forum"
+ (news))
+ ("pop3.el"
+ "Post Office Protocol (RFC 1460) interface"
+ (mail))
+ ("qp.el"
+ "Quoted-Printable functions"
+ (mail extensions))
+ ("rfc1843.el"
+ "HZ (rfc1843) decoding"
+ (news hz hz+ mail i18n))
+ ("rfc2045.el"
+ "Functions for decoding rfc2045 headers"
nil)
- ("reftex-parse.el"
- "parser functions for RefTeX"
+ ("rfc2047.el"
+ "functions for encoding and decoding rfc2047 messages"
nil)
- ("reftex-ref.el"
- "code to create labels and references with RefTeX"
+ ("rfc2104.el"
+ "RFC2104 Hashed Message Authentication Codes"
+ (mail))
+ ("rfc2231.el"
+ "Functions for decoding rfc2231 headers"
nil)
- ("reftex-sel.el"
- "the selection modes for RefTeX"
+ ("score-mode.el"
+ "mode for editing Gnus score files"
+ (news mail))
+ ("sha1.el"
+ "SHA1 Secure Hash Algorithm in Emacs-Lisp"
+ (sha1 fips 180-1))
+ ("sieve-manage.el"
+ "Implementation of the managesive protocol in elisp"
nil)
- ("reftex-toc.el"
- "RefTeX's table of contents mode"
+ ("sieve-mode.el"
+ "Sieve code editing commands for Emacs"
nil)
- ("reftex-vars.el"
- "configuration variables for RefTeX"
+ ("sieve.el"
+ "Utilities to manage sieve scripts"
nil)
- ("reftex.el"
- "minor mode for doing \\label, \\ref, \\cite, \\index in LaTeX"
- (tex))
- ("sgml-mode.el"
- "SGML- and HTML-editing modes"
- (wp hypermedia comm languages))
- ("spell.el"
- "spelling correction interface for Emacs"
- (wp unix))
- ("table.el"
- "create and edit WYSIWYG text based embedded tables"
- (wp convenience))
- ("tex-mode.el"
- "TeX, LaTeX, and SliTeX mode commands"
- (tex))
- ("texinfmt.el"
- "format Texinfo files into Info files"
- (maint tex docs))
- ("texinfo.el"
- "major mode for editing Texinfo files"
- (maint tex docs))
- ("texnfo-upd.el"
- "utilities for updating nodes and menus in Texinfo files"
- (maint tex docs))
- ("text-mode.el"
- "text mode, and its idiosyncratic commands"
- (wp))
- ("tildify.el"
- "adding hard spaces into texts"
- (text tex sgml wp))
- ("two-column.el"
- "minor mode for editing of two-column text"
- (wp))
- ("underline.el"
- "insert/remove underlining (done by overstriking) in Emacs"
- (wp))
- ("url-about.el"
- "Show internal URLs"
- (comm data processes hypermedia))
- ("url-auth.el"
- "Uniform Resource Locator authorization modules"
- (comm data processes hypermedia))
- ("url-cache.el"
- "Uniform Resource Locator retrieval tool"
- (comm data processes hypermedia))
- ("url-cid.el"
- "Content-ID URL loader"
- (comm data processes))
- ("url-cookie.el"
- "Netscape Cookie support"
- (comm data processes hypermedia))
- ("url-dav.el"
- "WebDAV support"
- (url vc))
- ("url-dired.el"
- "URL Dired minor mode"
- (comm files))
- ("url-expand.el"
- "expand-file-name for URLs"
- (comm data processes))
- ("url-file.el"
- "File retrieval code"
- (comm data processes))
- ("url-ftp.el"
- "FTP wrapper"
- (comm data processes))
- ("url-gw.el"
- "Gateway munging for URL loading"
- (comm data processes))
- ("url-handlers.el"
- "file-name-handler stuff for URL loading"
- (comm data processes hypermedia))
- ("url-history.el"
- "Global history tracking for URL package"
- (comm data processes hypermedia))
- ("url-http.el"
- "HTTP retrieval routines"
- (comm data processes))
- ("url-imap.el"
- "IMAP retrieval routines"
- (comm data processes))
- ("url-irc.el"
- "IRC URL interface"
- (comm data processes))
- ("url-ldap.el"
- "LDAP Uniform Resource Locator retrieval code"
- (comm data processes))
- ("url-mailto.el"
- "Mail Uniform Resource Locator retrieval code"
- (comm data processes))
- ("url-methods.el"
- "Load URL schemes as needed"
- (comm data processes hypermedia))
- ("url-misc.el"
- "Misc Uniform Resource Locator retrieval code"
- (comm data processes))
- ("url-news.el"
- "News Uniform Resource Locator retrieval code"
- (comm data processes))
- ("url-nfs.el"
- "NFS URL interface"
- (comm data processes))
- ("url-ns.el"
- "Various netscape-ish functions for proxy definitions"
- (comm data processes hypermedia))
- ("url-parse.el"
- "Uniform Resource Locator parser"
- (comm data processes))
- ("url-privacy.el"
- "Global history tracking for URL package"
- (comm data processes hypermedia))
- ("url-proxy.el"
- "Proxy server support"
- (comm data processes hypermedia))
- ("url-util.el"
- "Miscellaneous helper routines for URL library"
- (comm data processes))
- ("url-vars.el"
- "Variables for Uniform Resource Locator tool"
- (comm data processes hypermedia))
- ("url.el"
- "Uniform Resource Locator retrieval tool"
- (comm data processes hypermedia))
- ("vc-dav.el"
- "vc.el support for WebDAV"
- (url vc))
+ ("smiley.el"
+ "displaying smiley faces"
+ (news mail multimedia))
+ ("smime.el"
+ "S/MIME support library"
+ (smime x.509 pem openssl))
+ ("spam-report.el"
+ "Reporting spam"
+ (network))
+ ("spam-stat.el"
+ "detecting spam based on statistics"
+ (network))
+ ("spam.el"
+ "Identifying spam"
+ (network))
+ ("starttls.el"
+ "STARTTLS functions"
+ (tls ssl openssl gnutls mail news))
+ ("utf7.el"
+ "UTF-7 encoding/decoding for Emacs"
+ (mail))
+ ("uudecode.el"
+ "elisp native uudecode"
+ (uudecode news))
+ ("webmail.el"
+ "interface of web mail"
+ (hotmail netaddress my-deja netscape))
+ ("yenc.el"
+ "elisp native yenc decoder"
+ (yenc news))
))
(provide 'finder-inf)
"Assoc list mapping file names to description & keyword lists.")
(defvar generated-finder-keywords-file "finder-inf.el"
- "File \\[finder-compile-keywords] puts finder keywords into.")
+ "The function `finder-compile-keywords' writes keywords into this file.")
(defun finder-compile-keywords (&rest dirs)
"Regenerate the keywords association list into `generated-finder-keywords-file'.
finder directory, \\[finder-exit] = quit, \\[finder-summary] = help")))
(defun finder-exit ()
- "Exit Finder mode and kill the buffer."
+ "Exit Finder mode and kill all Finder-related buffers."
(interactive)
(or (one-window-p t)
(delete-window))
\(which directs the caller to fontify a default region).
This function should preserve the match-data.
The region it returns may start or end in the middle of a line.")
+(make-variable-buffer-local 'font-lock-extend-after-change-region-function)
(defun font-lock-fontify-buffer ()
"Fontify the current buffer the way the function `font-lock-mode' would."
+2008-06-18 Aidan Kehoe <kehoea@parhasard.net>
+
+ * gnus-util.el (gnus-put-display-table, gnus-get-display-table): New
+ macros that expand to an `aset'/`aref' call under Emacs, and to a
+ runtime choice under XEmacs.
+
+ * gnus-sum.el (gnus-summary-set-display-table): Use
+ `gnus-put-display-table', `gnus-get-display-table',
+ `gnus-set-display-table' for the display table, instead of `aset'.
+
+2008-06-05 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * message.el (message-disassociate-draft): Revert 2008-03-18 change.
+
+2008-05-25 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * gnus-art.el (gnus-button-alist): Exclude newline in RFC2396-compliant
+ url pattern; remove duplicate one.
+ (gnus-article-extend-url-button): New function.
+ (gnus-article-add-buttons): Use it.
+ (gnus-button-push): Use concatenated url that it makes.
+
+2008-05-07 Teodor Zlatanov <tzz@lifelogs.com>
+
+ * gnus-registry.el: Adjusted copyright dates and added a keyword.
+
+2008-04-24 Luca Capello <luca@pca.it> (tiny change)
+
+ * mm-encode.el (mm-safer-encoding): Add optional argument `type'.
+ Don't use QP for message/rfc822.
+ (mm-content-transfer-encoding): Pass `type' to mm-safer-encoding.
+
+2008-04-13 Reiner Steib <Reiner.Steib@gmx.de>
+
+ [Backport GNKSA related changes from the Gnus trunk.]
+
+ * message.el (message-fill-column): New variable.
+ (message-mode): Use it.
+
+ * message.el (message-signature-separator): Change default. Improve
+ custom type.
+ (message-cite-function): Change default to
+ message-cite-original-without-signature.
+
+ * gnus-sum.el (gnus-summary-make-menu-bar): Add message-cite-function
+ toggle.
+
+ * message.el (message-check-news-body-syntax): Fix signature check.
+ (message-setup-1): Mark buffer as unmodified _after_ running
+ message-setup-hook and handling message-alternative-emails.
+ (message-shorten-references): Be more strict when building list of
+ valid references to comply with GNKSA.
+
+2008-04-12 Adrian Aichner <adrian@xemacs.org>
+
+ * gnus-sum.el (gnus-summary-goto-subject): Typo fix.
+
+2008-04-12 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus-diary.el (gnus-article-edit-mode-map, message-mode-map): Remove
+ binding for `gnus-diary-version'. Bind `gnus-diary-check-message' to
+ `C-c C-f d'.
+
+2008-03-29 Sven Joachim <svenjoac@gmx.de>
+
+ * gnus-sum.el (gnus-summary-make-menu-bar): Add missing dots.
+
2008-03-24 Reiner Steib <Reiner.Steib@gmx.de>
* message.el (message-cite-original-without-signature): Mention
;; here to determine where it ends.
1 (>= gnus-button-emacs-level 1) gnus-button-handle-describe-key 3)
;; This is how URLs _should_ be embedded in text (RFC 1738, RFC 2396)...
- ("<URL: *\\([^<>]*\\)>"
+ ("<URL: *\\([^\n<>]*\\)>"
1 (>= gnus-button-browse-level 0) gnus-button-embedded-url 1)
;; RFC 2396 (2.4.3., delims) ...
- ("\"URL: *\\([^\"]*\\)\""
- 1 (>= gnus-button-browse-level 0) gnus-button-embedded-url 1)
- ;; RFC 2396 (2.4.3., delims) ...
- ("\"URL: *\\([^\"]*\\)\""
+ ("\"URL: *\\([^\n\"]*\\)\""
1 (>= gnus-button-browse-level 0) gnus-button-embedded-url 1)
;; Raw URLs.
(gnus-button-url-regexp
(setq regexp (eval (car entry)))
(goto-char beg)
(while (re-search-forward regexp nil t)
- (let* ((start (and entry (match-beginning (nth 1 entry))))
- (end (and entry (match-end (nth 1 entry))))
- (from (match-beginning 0)))
+ (let ((start (match-beginning (nth 1 entry)))
+ (end (match-end (nth 1 entry)))
+ (from (match-beginning 0)))
(when (and (or (eq t (nth 2 entry))
(eval (nth 2 entry)))
(not (gnus-button-in-region-p
start end 'gnus-callback)))
;; That optional form returned non-nil, so we add the
;; button.
- (gnus-article-add-button
- start end 'gnus-button-push
- (car (push (set-marker (make-marker) from)
- gnus-button-marker-list))))))))))
+ (setq from (set-marker (make-marker) from))
+ (push from gnus-button-marker-list)
+ (unless (and (eq (car entry) 'gnus-button-url-regexp)
+ (gnus-article-extend-url-button from start end))
+ (gnus-article-add-button start end
+ 'gnus-button-push from)))))))))
+
+(defun gnus-article-extend-url-button (beg start end)
+ "Extend url button if url is folded into two or more lines.
+Return non-nil if button is extended. BEG is a marker that points to
+the beginning position of a text containing url. START and END are
+the endpoints of a url button before it is extended. The concatenated
+url is put as the `gnus-button-url' overlay property on the button."
+ (let ((opoint (point))
+ (points (list start end))
+ url delim regexp)
+ (prog1
+ (when (and (progn
+ (goto-char end)
+ (not (looking-at "[\t ]*[\">]")))
+ (progn
+ (goto-char start)
+ (string-match
+ "\\(?:\"\\|\\(<\\)\\)[\t ]*\\(?:url[\t ]*:[\t ]*\\)?\\'"
+ (buffer-substring (point-at-bol) start)))
+ (progn
+ (setq url (list (buffer-substring start end))
+ delim (if (match-beginning 1) ">" "\""))
+ (beginning-of-line)
+ (setq regexp (concat
+ (when (and (looking-at
+ message-cite-prefix-regexp)
+ (< (match-end 0) start))
+ (regexp-quote (match-string 0)))
+ "\
+\[\t ]*\\(?:\\([^\t\n \">]+\\)[\t ]*$\\|\\([^\t\n \">]*\\)[\t ]*"
+ delim "\\)"))
+ (while (progn
+ (forward-line 1)
+ (and (looking-at regexp)
+ (prog1
+ (match-beginning 1)
+ (push (or (match-string 2)
+ (match-string 1))
+ url)
+ (push (setq end (or (match-end 2)
+ (match-end 1)))
+ points)
+ (push (or (match-beginning 2)
+ (match-beginning 1))
+ points)))))
+ (match-beginning 2)))
+ (let (gnus-article-mouse-face widget-mouse-face)
+ (while points
+ (gnus-article-add-button (pop points) (pop points)
+ 'gnus-button-push beg)))
+ (let ((overlay (gnus-make-overlay start end)))
+ (gnus-overlay-put overlay 'evaporate t)
+ (gnus-overlay-put overlay 'gnus-button-url
+ (list (mapconcat 'identity (nreverse url) "")))
+ (when gnus-article-mouse-face
+ (gnus-overlay-put overlay 'mouse-face gnus-article-mouse-face)))
+ t)
+ (goto-char opoint))))
;; Add buttons to the head of an article.
(defun gnus-article-add-buttons-to-head ()
(let* ((entry (gnus-button-entry))
(inhibit-point-motion-hooks t)
(fun (nth 3 entry))
- (args (mapcar (lambda (group)
- (let ((string (match-string group)))
- (gnus-set-text-properties
- 0 (length string) nil string)
- string))
- (nthcdr 4 entry))))
+ (args (or (and (eq (car entry) 'gnus-button-url-regexp)
+ (get-char-property marker 'gnus-button-url))
+ (mapcar (lambda (group)
+ (let ((string (match-string group)))
+ (set-text-properties
+ 0 (length string) nil string)
+ string))
+ (nthcdr 4 entry)))))
(cond
((fboundp fun)
(apply fun args))
(add-hook 'nndiary-request-accept-article-hooks
(lambda () (gnus-diary-check-message nil)))
-(define-key message-mode-map "\C-cDc" 'gnus-diary-check-message)
-(define-key gnus-article-edit-mode-map "\C-cDc" 'gnus-diary-check-message)
+(define-key message-mode-map "\C-c\C-fd" 'gnus-diary-check-message)
+(define-key gnus-article-edit-mode-map "\C-c\C-fd" 'gnus-diary-check-message)
;; The end ==================================================================
(interactive)
(message "NNDiary version %s" nndiary-version))
-(define-key message-mode-map "\C-cDv" 'gnus-diary-version)
-(define-key gnus-article-edit-mode-map "\C-cDv" 'gnus-diary-version)
-
-
(provide 'gnus-diary)
;;; arch-tag: 98467e70-337e-4ddc-b92d-45d403ff1b4b
;;; gnus-registry.el --- article registry for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
;; Author: Ted Zlatanov <tzz@lifelogs.com>
-;; Keywords: news
+;; Keywords: news registry
;; This file is part of GNU Emacs.
["Set mark below..." gnus-score-set-mark-below t]
["Set expunge below..." gnus-score-set-expunge-below t]
["Edit current score file" gnus-score-edit-current-scores t]
- ["Edit score file" gnus-score-edit-file t]
+ ["Edit score file..." gnus-score-edit-file t]
["Trace score" gnus-score-find-trace t]
["Find words" gnus-score-find-favourite-words t]
["Rescore buffer" gnus-summary-rescore t]
["Followup via news" gnus-summary-followup-to-mail t]
["Followup via news and yank"
gnus-summary-followup-to-mail-with-original t]
+ ["Strip signature on reply"
+ (lambda ()
+ (interactive)
+ (if (not (memq message-cite-function
+ '(message-cite-original-without-signature
+ message-cite-original)))
+ ;; Stupid workaround for XEmacs not honoring :visible.
+ (message "Can't toggle this value of `message-cite-function'")
+ (setq message-cite-function
+ (if (eq message-cite-function
+ 'message-cite-original-without-signature)
+ 'message-cite-original
+ 'message-cite-original-without-signature))))
+ ;; XEmacs barfs on :visible.
+ ,@(if (featurep 'xemacs) nil
+ '(:visible (memq message-cite-function
+ '(message-cite-original-without-signature
+ message-cite-original))))
+ :style toggle
+ :selected (eq message-cite-function
+ 'message-cite-original-without-signature)
+ ,@(if (featurep 'xemacs) nil
+ '(:help "Strip signature from cited article when replying."))]
;;("Draft"
;;["Send" gnus-summary-send-draft t]
;;["Send bounced" gnus-resend-bounced-mail t])
(i 32))
;; Nix out all the control chars...
(while (>= (setq i (1- i)) 0)
- (aset table i [??]))
+ (gnus-put-display-table i [??] table))
;; ... but not newline and cr, of course. (cr is necessary for the
;; selective display).
- (aset table ?\n nil)
- (aset table ?\r nil)
+ (gnus-put-display-table ?\n nil table)
+ (gnus-put-display-table ?\r nil table)
;; We keep TAB as well.
- (aset table ?\t nil)
+ (gnus-put-display-table ?\t nil table)
;; We nix out any glyphs 127 through 255, or 127 through 159 in
;; Emacs 23 (unicode), that are not set already.
(let ((i (if (ignore-errors (= (make-char 'latin-iso8859-1 160) 160))
256)))
(while (>= (setq i (1- i)) 127)
;; Only modify if the entry is nil.
- (unless (aref table i)
- (aset table i [??]))))
+ (unless (gnus-get-display-table i table)
+ (gnus-put-display-table i [??] table))))
(setq buffer-display-table table)))
(defun gnus-summary-set-article-display-arrow (pos)
(gnus-summary-position-point))
(defun gnus-summary-goto-subject (article &optional force silent)
- "Go the subject line of ARTICLE.
+ "Go to the subject line of ARTICLE.
If FORCE, also allow jumping to articles not currently shown."
(interactive "nArticle number: ")
(unless (numberp article)
;; that intends to handle the quit signal next time.
(eval '(ignore nil))))))
+(defmacro gnus-put-display-table (range value display-table)
+ "Set the value for char RANGE to VALUE in DISPLAY-TABLE. "
+ (if (featurep 'xemacs)
+ (progn
+ `(if (fboundp 'put-display-table)
+ (put-display-table ,range ,value ,display-table)
+ (if (sequencep ,display-table)
+ (aset ,display-table ,range ,value)
+ (put-char-table ,range ,value ,display-table))))
+ `(aset ,display-table ,range ,value)))
+
+(defmacro gnus-get-display-table (character display-table)
+ "Find value for CHARACTER in DISPLAY-TABLE. "
+ (if (featurep 'xemacs)
+ `(if (fboundp 'get-display-table)
+ (get-display-table ,character ,display-table)
+ (if (sequencep ,display-table)
+ (aref ,display-table ,character)
+ (get-char-table ,character ,display-table)))
+ `(aref ,display-table ,character)))
+
(provide 'gnus-util)
;;; arch-tag: f94991af-d32b-4c97-8c26-ca12a934de49
;;; End of variables adopted from `message-utils.el'.
-;;;###autoload
-(defcustom message-signature-separator "^-- *$"
- "Regexp matching the signature separator."
- :type 'regexp
+(defcustom message-signature-separator "^-- $"
+ "Regexp matching the signature separator.
+This variable is used to strip off the signature from quoted text
+when `message-cite-function' is
+`message-cite-original-without-signature'. Most useful values
+are \"^-- $\" (strict) and \"^-- *$\" (loose; allow missing
+whitespace)."
+ :type '(choice (const :tag "strict" "^-- $")
+ (const :tag "loose" "^-- *$")
+ regexp)
+ :version "22.3" ;; Gnus 5.10.12 (changed default)
:link '(custom-manual "(message)Various Message Variables")
:group 'message-various)
(const :tag "All" t)
(repeat (sexp :tag "Header"))))
+(defcustom message-fill-column 72
+ "Column beyond which automatic line-wrapping should happen.
+Local value for message buffers. If non-nil, also turn on
+auto-fill in message buffers."
+ :group 'message-various
+ ;; :link '(custom-manual "(message)Message Headers")
+ :type '(choice (const :tag "Don't turn on auto fill" nil)
+ (integer)))
+
(defcustom message-setup-hook nil
"Normal hook, run each time a new outgoing message is initialized.
The function `message-setup' runs this hook."
:type 'integer)
;;;###autoload
-(defcustom message-cite-function 'message-cite-original
+(defcustom message-cite-function 'message-cite-original-without-signature
"*Function for citing an original message.
Predefined functions include `message-cite-original' and
`message-cite-original-without-signature'.
(function-item sc-cite-original)
(function :tag "Other"))
:link '(custom-manual "(message)Insertion Variables")
+ :version "22.3" ;; Gnus 5.10.12 (changed default)
:group 'message-insertion)
;;;###autoload
(set (make-local-variable 'message-checksum) nil)
(set (make-local-variable 'message-mime-part) 0)
(message-setup-fill-variables)
+ (when message-fill-column
+ (setq fill-column message-fill-column)
+ (turn-on-auto-fill))
;; Allow using comment commands to add/remove quoting.
;; (set (make-local-variable 'comment-start) message-yank-prefix)
(when message-yank-prefix
;; Check the length of the signature.
(message-check 'signature
(goto-char (point-max))
- (if (> (count-lines (point) (point-max)) 5)
- (y-or-n-p
- (format
- "Your .sig is %d lines; it should be max 4. Really post? "
- (1- (count-lines (point) (point-max)))))
- t))
+ (if (not (re-search-backward message-signature-separator nil t))
+ t
+ (if (>= (count-lines (1+ (point-at-eol)) (point-max)) 5)
+ (if (message-gnksa-enable-p 'signature)
+ (y-or-n-p
+ (format "Signature is excessively long (%d lines). Really post? "
+ (count-lines (1+ (point-at-eol)) (point-max))))
+ (message "Denied posting -- Excessive signature.")
+ nil)
+ t)))
;; Ensure that text follows last quoted portion.
(message-check 'quoting-style
(goto-char (point-max))
(with-temp-buffer
(insert references)
(goto-char (point-min))
- ;; Cons a list of valid references.
- (while (re-search-forward "<[^>]+>" nil t)
+ ;; Cons a list of valid references. GNKSA says we must not include MIDs
+ ;; with whitespace or missing brackets (7.a "Does not propagate broken
+ ;; Message-IDs in original References").
+ (while (re-search-forward "<[^ <]+@[^ <]+>" nil t)
(push (match-string 0) refs))
(setq refs (nreverse refs)
count (length refs)))
(save-restriction
(message-narrow-to-headers)
(run-hooks 'message-header-setup-hook))
- (set-buffer-modified-p nil)
(setq buffer-undo-list nil)
+ ;; Gnus posting styles are applied via buffer-local `message-setup-hook'
+ ;; values.
(run-hooks 'message-setup-hook)
;; Do this last to give it precedence over posting styles, etc.
(when (message-mail-p)
(if message-alternative-emails
(message-use-alternative-email-as-from))))
(message-position-point)
+ ;; Allow correct handling of `message-checksum' in `message-yank-original':
+ (set-buffer-modified-p nil)
(undo-boundary))
(defun message-set-auto-save-file-name ()
"Disassociate the message buffer from the drafts directory."
(when message-draft-article
(nndraft-request-expire-articles
- (list message-draft-article) "nndraft:drafts" nil t)))
+ (list message-draft-article) "drafts" nil t)))
(defun message-insert-headers ()
"Generate the headers for the article."
"application/octet-stream"
(mailcap-extension-to-mime (match-string 0 file))))
-(defun mm-safer-encoding (encoding)
+(defun mm-safer-encoding (encoding &optional type)
"Return an encoding similar to ENCODING but safer than it."
(cond
((eq encoding '7bit) '7bit) ;; 7bit is considered safe.
- ((memq encoding '(8bit quoted-printable)) 'quoted-printable)
+ ((memq encoding '(8bit quoted-printable))
+ ;; According to RFC2046, 5.2.1, RFC822 Subtype, "quoted-printable" is not
+ ;; a valid encoding for message/rfc822:
+ ;; No encoding other than "7bit", "8bit", or "binary" is permitted for the
+ ;; body of a "message/rfc822" entity.
+ (if (string= type "message/rfc822") '8bit 'quoted-printable))
;; The remaining encodings are binary and base64 (and perhaps some
;; non-standard ones), which are both turned into base64.
- (t 'base64)))
+ (t (if (string= type "message/rfc822") 'binary 'base64))))
(defun mm-encode-content-transfer-encoding (encoding &optional type)
"Encode the current buffer with ENCODING for MIME type TYPE.
(mm-qp-or-base64)
(cadr (car rules)))))
(if mm-use-ultra-safe-encoding
- (mm-safer-encoding encoding)
+ (mm-safer-encoding encoding type)
encoding))))
(pop rules)))))
(provide 'nnrss)
-
+;; arch-tag: 12910c07-0cdf-44fb-8d2c-416ded64c267
;;; nnrss.el ends here
-
-;;; arch-tag: 12910c07-0cdf-44fb-8d2c-416ded64c267
Write active REGEXPs into buffer as comments (if possible). They may
be read the next time file is loaded or when the \\[hi-lock-find-patterns] command
is issued. The inserted regexps are in the form of font lock keywords.
- (See `font-lock-keywords'.) They may be edited and re-loaded with \\[hi-lock-find-patterns],
- any valid `font-lock-keywords' form is acceptable. When a file is
- loaded the patterns are read if `hi-lock-file-patterns-policy is
+ (See `font-lock-keywords'.) They may be edited and re-loaded with \\[hi-lock-find-patterns],
+ any valid `font-lock-keywords' form is acceptable. When a file is
+ loaded the patterns are read if `hi-lock-file-patterns-policy' is
'ask and the user responds y to the prompt, or if
`hi-lock-file-patterns-policy' is bound to a function and that
function returns t.
:group 'icomplete)
(defcustom icomplete-compute-delay .3
- "*Completions-computation stall, used only with large-number
-completions - see `icomplete-delay-completions-threshold'."
+ "*Completions-computation stall, used only with large-number completions.
+See `icomplete-delay-completions-threshold'."
:type 'number
:group 'icomplete)
(defcustom icomplete-delay-completions-threshold 400
- "*Pending-completions number over which to apply icomplete-compute-delay."
+ "*Pending-completions number over which to apply `icomplete-compute-delay'."
:type 'integer
:group 'icomplete)
(add-hook 'icomplete-post-command-hook 'icomplete-exhibit)
(defun icomplete-get-keys (func-name)
- "Return strings naming keys bound to `func-name', or nil if none.
+ "Return strings naming keys bound to FUNC-NAME, or nil if none.
Examines the prior, not current, buffer, presuming that current buffer
is minibuffer."
(if (commandp func-name)
(setq mode-name "Image")
(setq major-mode 'image-mode)
(add-hook 'change-major-mode-hook 'image-toggle-display-text nil t)
- (if (and (display-images-p)
- (not (get-text-property (point-min) 'display)))
- (image-toggle-display)
- ;; Set next vars when image is already displayed but local
- ;; variables were cleared by kill-all-local-variables
- (use-local-map image-mode-map)
- (setq cursor-type nil truncate-lines t))
+ (if (display-images-p)
+ (if (not (get-text-property (point-min) 'display))
+ (image-toggle-display)
+ ;; Set next vars when image is already displayed but local
+ ;; variables were cleared by kill-all-local-variables
+ (use-local-map image-mode-map)
+ (setq cursor-type nil truncate-lines t))
+ (use-local-map image-mode-text-map))
(run-mode-hooks 'image-mode-hook)
(if (display-images-p)
(message "%s" (concat
keys)))
+;;;###autoload
(defun kmacro-exec-ring-item (item arg)
"Execute item ITEM from the macro ring."
;; Use counter and format specific to the macro on the ring!
;;;### (autoloads (change-log-merge add-log-current-defun change-log-mode
;;;;;; add-change-log-entry-other-window add-change-log-entry find-change-log
;;;;;; prompt-for-change-log-name add-log-mailing-address add-log-full-name
-;;;;;; add-log-current-defun-function) "add-log" "add-log.el" (18336
-;;;;;; 60192))
+;;;;;; add-log-current-defun-function) "add-log" "add-log.el" (18419
+;;;;;; 63244))
;;; Generated autoloads from add-log.el
(defvar add-log-current-defun-function nil "\
\f
;;;### (autoloads (batch-update-autoloads update-directory-autoloads
;;;;;; update-file-autoloads) "autoload" "emacs-lisp/autoload.el"
-;;;;;; (18310 14580))
+;;;;;; (18430 50673))
;;; Generated autoloads from emacs-lisp/autoload.el
(autoload (quote update-file-autoloads) "autoload" "\
;;;;;; batch-byte-compile-if-not-done display-call-tree byte-compile
;;;;;; compile-defun byte-compile-file byte-recompile-directory
;;;;;; byte-force-recompile byte-compile-warnings-safe-p) "bytecomp"
-;;;;;; "emacs-lisp/bytecomp.el" (18310 14580))
+;;;;;; "emacs-lisp/bytecomp.el" (18593 55295))
;;; Generated autoloads from emacs-lisp/bytecomp.el
(put 'byte-compile-dynamic 'safe-local-variable 'booleanp)
(put 'byte-compile-disable-print-circle 'safe-local-variable 'booleanp)
(autoload (quote byte-compile-file) "bytecomp" "\
Compile a file of Lisp code named FILENAME into a file of byte code.
The output file's name is generated by passing FILENAME to the
-`byte-compile-dest-file' function (which see).
+function `byte-compile-dest-file' (which see).
With prefix arg (noninteractively: 2nd arg), LOAD the file after compiling.
The value is non-nil if there were no errors, nil if errors.
;;;***
\f
;;;### (autoloads (list-yahrzeit-dates) "cal-hebrew" "calendar/cal-hebrew.el"
-;;;;;; (18310 14579))
+;;;;;; (18489 51007))
;;; Generated autoloads from calendar/cal-hebrew.el
(autoload (quote list-yahrzeit-dates) "cal-hebrew" "\
;;;### (autoloads (defmath calc-embedded-activate calc-embedded calc-grab-rectangle
;;;;;; calc-grab-region full-calc-keypad calc-keypad calc-eval quick-calc
;;;;;; full-calc calc calc-dispatch calc-settings-file) "calc" "calc/calc.el"
-;;;;;; (18310 14579))
+;;;;;; (18417 40519))
;;; Generated autoloads from calc/calc.el
(defvar calc-settings-file (convert-standard-filename "~/.calc.el") "\
;;;;;; mark-holidays-in-calendar view-calendar-holidays-initially
;;;;;; calendar-remove-frame-by-deleting mark-diary-entries-in-calendar
;;;;;; view-diary-entries-initially calendar-offset) "calendar"
-;;;;;; "calendar/calendar.el" (18310 14580))
+;;;;;; "calendar/calendar.el" (18593 55294))
;;; Generated autoloads from calendar/calendar.el
(defvar calendar-offset 0 "\
;;;***
\f
;;;### (autoloads (c-guess-basic-syntax) "cc-engine" "progmodes/cc-engine.el"
-;;;;;; (18368 29740))
+;;;;;; (18524 49166))
;;; Generated autoloads from progmodes/cc-engine.el
(autoload (quote c-guess-basic-syntax) "cc-engine" "\
\f
;;;### (autoloads (pike-mode idl-mode java-mode objc-mode c++-mode
;;;;;; c-mode c-initialize-cc-mode) "cc-mode" "progmodes/cc-mode.el"
-;;;;;; (18383 1613))
+;;;;;; (18488 2751))
;;; Generated autoloads from progmodes/cc-mode.el
(autoload (quote c-initialize-cc-mode) "cc-mode" "\
;;;***
\f
;;;### (autoloads (c-set-offset c-add-style c-set-style) "cc-styles"
-;;;;;; "progmodes/cc-styles.el" (18368 9297))
+;;;;;; "progmodes/cc-styles.el" (18578 10872))
;;; Generated autoloads from progmodes/cc-styles.el
(autoload (quote c-set-style) "cc-styles" "\
;;;### (autoloads (comint-redirect-results-list-from-process comint-redirect-results-list
;;;;;; comint-redirect-send-command-to-process comint-redirect-send-command
;;;;;; comint-run make-comint make-comint-in-buffer) "comint" "comint.el"
-;;;;;; (18326 18335))
+;;;;;; (18612 36171))
;;; Generated autoloads from comint.el
(defvar comint-output-filter-functions (quote (comint-postoutput-scroll-to-bottom comint-watch-for-password-prompt)) "\
;;;;;; compilation-shell-minor-mode compilation-mode compilation-start
;;;;;; compile compilation-disable-input compile-command compilation-search-path
;;;;;; compilation-ask-about-save compilation-window-height compilation-mode-hook)
-;;;;;; "compile" "progmodes/compile.el" (18368 9297))
+;;;;;; "compile" "progmodes/compile.el" (18574 9600))
;;; Generated autoloads from progmodes/compile.el
(defvar compilation-mode-hook nil "\
;;;;;; customize-mode customize customize-save-variable customize-set-variable
;;;;;; customize-set-value custom-menu-sort-alphabetically custom-buffer-sort-alphabetically
;;;;;; custom-browse-sort-alphabetically) "cus-edit" "cus-edit.el"
-;;;;;; (18310 14567))
+;;;;;; (18580 52460))
;;; Generated autoloads from cus-edit.el
(defvar custom-browse-sort-alphabetically nil "\
;;;***
\f
;;;### (autoloads (dabbrev-expand dabbrev-completion) "dabbrev" "dabbrev.el"
-;;;;;; (18310 14568))
+;;;;;; (18611 12227))
;;; Generated autoloads from dabbrev.el
(define-key esc-map "/" 'dabbrev-expand)
(define-key esc-map [?\C-/] 'dabbrev-completion)
;;;### (autoloads (desktop-revert desktop-save-in-desktop-dir desktop-change-dir
;;;;;; desktop-load-default desktop-read desktop-remove desktop-save
;;;;;; desktop-clear desktop-locals-to-save desktop-save-mode) "desktop"
-;;;;;; "desktop.el" (18383 1604))
+;;;;;; "desktop.el" (18597 43990))
;;; Generated autoloads from desktop.el
(defvar desktop-save-mode nil "\
;;;***
\f
;;;### (autoloads (diary-mode diary-mail-entries diary) "diary-lib"
-;;;;;; "calendar/diary-lib.el" (18310 14580))
+;;;;;; "calendar/diary-lib.el" (18593 55294))
;;; Generated autoloads from calendar/diary-lib.el
(autoload (quote diary) "diary-lib" "\
;;;***
\f
;;;### (autoloads (diff-minor-mode diff-mode) "diff-mode" "diff-mode.el"
-;;;;;; (18408 28171))
+;;;;;; (18449 15659))
;;; Generated autoloads from diff-mode.el
(autoload (quote diff-mode) "diff-mode" "\
;;;;;; dired dired-copy-preserve-time dired-dwim-target dired-keep-marker-symlink
;;;;;; dired-keep-marker-hardlink dired-keep-marker-copy dired-keep-marker-rename
;;;;;; dired-trivial-filenames dired-ls-F-marks-symlinks dired-listing-switches)
-;;;;;; "dired" "dired.el" (18397 19038))
+;;;;;; "dired" "dired.el" (18425 14914))
;;; Generated autoloads from dired.el
(defvar dired-listing-switches "-al" "\
;;;;;; dired-run-shell-command dired-do-shell-command dired-clean-directory
;;;;;; dired-do-print dired-do-touch dired-do-chown dired-do-chgrp
;;;;;; dired-do-chmod dired-compare-directories dired-backup-diff
-;;;;;; dired-diff) "dired-aux" "dired-aux.el" (18310 14568))
+;;;;;; dired-diff) "dired-aux" "dired-aux.el" (18568 43717))
;;; Generated autoloads from dired-aux.el
(autoload (quote dired-diff) "dired-aux" "\
;;;***
\f
;;;### (autoloads (dired-do-relsymlink dired-jump) "dired-x" "dired-x.el"
-;;;;;; (18310 14568))
+;;;;;; (18611 12215))
;;; Generated autoloads from dired-x.el
(autoload (quote dired-jump) "dired-x" "\
\f
;;;### (autoloads (edebug-all-forms edebug-all-defs edebug-eval-top-level-form
;;;;;; edebug-basic-spec edebug-all-forms edebug-all-defs) "edebug"
-;;;;;; "emacs-lisp/edebug.el" (18368 9295))
+;;;;;; "emacs-lisp/edebug.el" (18615 8002))
;;; Generated autoloads from emacs-lisp/edebug.el
(defvar edebug-all-defs nil "\
;;;***
\f
;;;### (autoloads (edt-emulation-on edt-set-scroll-margins) "edt"
-;;;;;; "emulation/edt.el" (18310 14582))
+;;;;;; "emulation/edt.el" (18601 51444))
;;; Generated autoloads from emulation/edt.el
(autoload (quote edt-set-scroll-margins) "edt" "\
;;;***
\f
;;;### (autoloads (enriched-decode enriched-encode enriched-mode)
-;;;;;; "enriched" "textmodes/enriched.el" (18310 14604))
+;;;;;; "enriched" "textmodes/enriched.el" (18568 43591))
;;; Generated autoloads from textmodes/enriched.el
(autoload (quote enriched-mode) "enriched" "\
;;;***
\f
-;;;### (autoloads (f90-mode) "f90" "progmodes/f90.el" (18310 14599))
+;;;### (autoloads (f90-mode) "f90" "progmodes/f90.el" (18593 55295))
;;; Generated autoloads from progmodes/f90.el
(autoload (quote f90-mode) "f90" "\
;;;;;; facemenu-remove-all facemenu-remove-face-props facemenu-set-read-only
;;;;;; facemenu-set-intangible facemenu-set-invisible facemenu-set-face-from-menu
;;;;;; facemenu-set-background facemenu-set-foreground facemenu-set-face)
-;;;;;; "facemenu" "facemenu.el" (18310 14569))
+;;;;;; "facemenu" "facemenu.el" (18612 9509))
;;; Generated autoloads from facemenu.el
(define-key global-map "\M-o" 'facemenu-keymap)
(autoload 'facemenu-keymap "facemenu" "Keymap for face-changing commands." t 'keymap)
;;;***
\f
-;;;### (autoloads nil "fill" "textmodes/fill.el" (18377 44624))
+;;;### (autoloads nil "fill" "textmodes/fill.el" (18612 9510))
;;; Generated autoloads from textmodes/fill.el
(put 'colon-double-space 'safe-local-variable 'booleanp)
\f
;;;### (autoloads (find-grep-dired find-name-dired find-dired find-name-arg
;;;;;; find-grep-options find-ls-subdir-switches find-ls-option)
-;;;;;; "find-dired" "find-dired.el" (18310 14569))
+;;;;;; "find-dired" "find-dired.el" (18418 29074))
;;; Generated autoloads from find-dired.el
(defvar find-ls-option (if (eq system-type (quote berkeley-unix)) (quote ("-ls" . "-gilsb")) (quote ("-exec ls -ld {} \\;" . "-ld"))) "\
;;;;;; find-variable find-variable-noselect find-function-other-frame
;;;;;; find-function-other-window find-function find-function-noselect
;;;;;; find-function-search-for-symbol find-library) "find-func"
-;;;;;; "emacs-lisp/find-func.el" (18310 14581))
+;;;;;; "emacs-lisp/find-func.el" (18597 43991))
;;; Generated autoloads from emacs-lisp/find-func.el
(autoload (quote find-library) "find-func" "\
;;;***
\f
;;;### (autoloads (finder-by-keyword finder-commentary finder-list-keywords)
-;;;;;; "finder" "finder.el" (18310 14569))
+;;;;;; "finder" "finder.el" (18593 55294))
;;; Generated autoloads from finder.el
(autoload (quote finder-list-keywords) "finder" "\
;;;***
\f
;;;### (autoloads (flymake-mode-off flymake-mode-on flymake-mode)
-;;;;;; "flymake" "progmodes/flymake.el" (18310 14600))
+;;;;;; "flymake" "progmodes/flymake.el" (18567 43650))
;;; Generated autoloads from progmodes/flymake.el
(autoload (quote flymake-mode) "flymake" "\
\f
;;;### (autoloads (flyspell-buffer flyspell-region flyspell-mode-off
;;;;;; turn-off-flyspell turn-on-flyspell flyspell-mode flyspell-prog-mode)
-;;;;;; "flyspell" "textmodes/flyspell.el" (18310 14604))
+;;;;;; "flyspell" "textmodes/flyspell.el" (18612 35635))
;;; Generated autoloads from textmodes/flyspell.el
(autoload (quote flyspell-prog-mode) "flyspell" "\
;;;***
\f
;;;### (autoloads (fortran-mode fortran-tab-mode-default) "fortran"
-;;;;;; "progmodes/fortran.el" (18310 14600))
+;;;;;; "progmodes/fortran.el" (18593 55295))
;;; Generated autoloads from progmodes/fortran.el
(defvar fortran-tab-mode-default nil "\
;;;***
\f
;;;### (autoloads (gdb-enable-debug gdb) "gdb-ui" "progmodes/gdb-ui.el"
-;;;;;; (18389 59107))
+;;;;;; (18612 9510))
;;; Generated autoloads from progmodes/gdb-ui.el
(autoload (quote gdb) "gdb-ui" "\
;;;***
\f
;;;### (autoloads (gnus-article-prepare-display) "gnus-art" "gnus/gnus-art.el"
-;;;;;; (18389 59107))
+;;;;;; (18490 24742))
;;; Generated autoloads from gnus/gnus-art.el
(autoload (quote gnus-article-prepare-display) "gnus-art" "\
;;;***
\f
;;;### (autoloads (gnus-user-format-function-D gnus-user-format-function-d)
-;;;;;; "gnus-diary" "gnus/gnus-diary.el" (18310 14585))
+;;;;;; "gnus-diary" "gnus/gnus-diary.el" (18448 4532))
;;; Generated autoloads from gnus/gnus-diary.el
(autoload (quote gnus-user-format-function-d) "gnus-diary" "\
;;;***
\f
;;;### (autoloads (gnus-registry-install-hooks gnus-registry-initialize)
-;;;;;; "gnus-registry" "gnus/gnus-registry.el" (18310 14586))
+;;;;;; "gnus-registry" "gnus/gnus-registry.el" (18490 24741))
;;; Generated autoloads from gnus/gnus-registry.el
(autoload (quote gnus-registry-initialize) "gnus-registry" "\
;;;***
\f
;;;### (autoloads (gdb-script-mode jdb pdb perldb xdb dbx sdb gud-gdb)
-;;;;;; "gud" "progmodes/gud.el" (18368 29740))
+;;;;;; "gud" "progmodes/gud.el" (18432 46544))
;;; Generated autoloads from progmodes/gud.el
(autoload (quote gud-gdb) "gud" "\
;;;### (autoloads (hi-lock-write-interactive-patterns hi-lock-unface-buffer
;;;;;; hi-lock-face-phrase-buffer hi-lock-face-buffer hi-lock-line-face-buffer
;;;;;; global-hi-lock-mode hi-lock-mode) "hi-lock" "hi-lock.el"
-;;;;;; (18310 14570))
+;;;;;; (18612 9509))
;;; Generated autoloads from hi-lock.el
(autoload (quote hi-lock-mode) "hi-lock" "\
Write active REGEXPs into buffer as comments (if possible). They may
be read the next time file is loaded or when the \\[hi-lock-find-patterns] command
is issued. The inserted regexps are in the form of font lock keywords.
- (See `font-lock-keywords'.) They may be edited and re-loaded with \\[hi-lock-find-patterns],
- any valid `font-lock-keywords' form is acceptable. When a file is
- loaded the patterns are read if `hi-lock-file-patterns-policy is
+ (See `font-lock-keywords'.) They may be edited and re-loaded with \\[hi-lock-find-patterns],
+ any valid `font-lock-keywords' form is acceptable. When a file is
+ loaded the patterns are read if `hi-lock-file-patterns-policy' is
'ask and the user responds y to the prompt, or if
`hi-lock-file-patterns-policy' is bound to a function and that
function returns t.
;;;***
\f
;;;### (autoloads (list-holidays holidays) "holidays" "calendar/holidays.el"
-;;;;;; (18310 14580))
+;;;;;; (18593 55294))
;;; Generated autoloads from calendar/holidays.el
(autoload (quote holidays) "holidays" "\
;;;***
\f
-;;;### (autoloads (icomplete-mode) "icomplete" "icomplete.el" (18326
-;;;;;; 18335))
+;;;### (autoloads (icomplete-mode) "icomplete" "icomplete.el" (18612
+;;;;;; 9509))
;;; Generated autoloads from icomplete.el
(defvar icomplete-mode nil "\
;;;***
\f
;;;### (autoloads (image-mode-maybe image-minor-mode image-mode)
-;;;;;; "image-mode" "image-mode.el" (18310 14571))
+;;;;;; "image-mode" "image-mode.el" (18615 34896))
;;; Generated autoloads from image-mode.el
(push '("\\.jpe?g\\'" . image-mode) auto-mode-alist)
(push '("\\.png\\'" . image-mode) auto-mode-alist)
\f
;;;### (autoloads (kmacro-end-call-mouse kmacro-end-and-call-macro
;;;;;; kmacro-end-or-call-macro kmacro-start-macro-or-insert-counter
-;;;;;; kmacro-call-macro kmacro-end-macro kmacro-start-macro) "kmacro"
-;;;;;; "kmacro.el" (18310 14572))
+;;;;;; kmacro-call-macro kmacro-end-macro kmacro-start-macro kmacro-exec-ring-item)
+;;;;;; "kmacro" "kmacro.el" (18584 56069))
;;; Generated autoloads from kmacro.el
(global-set-key "\C-x(" 'kmacro-start-macro)
(global-set-key "\C-x)" 'kmacro-end-macro)
(global-set-key "\C-x\C-k" 'kmacro-keymap)
(autoload 'kmacro-keymap "kmacro" "Keymap for keyboard macro commands." t 'keymap)
+(autoload (quote kmacro-exec-ring-item) "kmacro" "\
+Execute item ITEM from the macro ring.
+
+\(fn ITEM ARG)" nil nil)
+
(autoload (quote kmacro-start-macro) "kmacro" "\
Record subsequent keyboard input, defining a keyboard macro.
The commands are recorded even as they are executed.
\f
;;;### (autoloads (makefile-imake-mode makefile-bsdmake-mode makefile-makepp-mode
;;;;;; makefile-gmake-mode makefile-automake-mode makefile-mode)
-;;;;;; "make-mode" "progmodes/make-mode.el" (18310 14600))
+;;;;;; "make-mode" "progmodes/make-mode.el" (18432 19261))
;;; Generated autoloads from progmodes/make-mode.el
(autoload (quote makefile-mode) "make-mode" "\
;;;;;; message-signature-file message-signature message-indent-citation-function
;;;;;; message-cite-function message-yank-prefix message-citation-line-function
;;;;;; message-send-mail-function message-user-organization-file
-;;;;;; message-signature-separator message-from-style) "message"
-;;;;;; "gnus/message.el" (18408 28171))
+;;;;;; message-from-style) "message" "gnus/message.el" (18519 8938))
;;; Generated autoloads from gnus/message.el
(defvar message-from-style (quote default) "\
(custom-autoload (quote message-from-style) "message" t)
-(defvar message-signature-separator "^-- *$" "\
-Regexp matching the signature separator.")
-
-(custom-autoload (quote message-signature-separator) "message" t)
-
(defvar message-user-organization-file "/usr/lib/news/organization" "\
*Local news organization file.")
(custom-autoload (quote message-yank-prefix) "message" t)
-(defvar message-cite-function (quote message-cite-original) "\
+(defvar message-cite-function (quote message-cite-original-without-signature) "\
*Function for citing an original message.
Predefined functions include `message-cite-original' and
`message-cite-original-without-signature'.
;;;;;; uncomment-region comment-kill comment-set-column comment-indent
;;;;;; comment-indent-default comment-normalize-vars comment-multi-line
;;;;;; comment-padding comment-style comment-column) "newcomment"
-;;;;;; "newcomment.el" (18385 29912))
+;;;;;; "newcomment.el" (18421 31051))
;;; Generated autoloads from newcomment.el
(defalias (quote indent-for-comment) (quote comment-indent))
;;;***
\f
;;;### (autoloads (org-export-icalendar-combine-agenda-files org-export-icalendar-all-agenda-files
-;;;;;; org-export-icalendar-this-file org-diary org-tags-view org-todo-list
-;;;;;; org-agenda-list org-cycle-agenda-files org-batch-agenda org-agenda
+;;;;;; org-export-icalendar-this-file org-diary org-agenda-list-stuck-projects
+;;;;;; org-tags-view org-todo-list org-search-view org-agenda-list
+;;;;;; org-cycle-agenda-files org-batch-store-agenda-views org-store-agenda-views
+;;;;;; org-batch-agenda-csv org-batch-agenda org-agenda org-agenda-to-appt
;;;;;; org-remember-handler org-remember org-remember-apply-template
-;;;;;; org-remember-annotation org-store-link orgtbl-mode turn-on-orgtbl
-;;;;;; org-global-cycle org-cycle org-mode) "org" "textmodes/org.el"
-;;;;;; (18310 14605))
+;;;;;; org-remember-annotation org-remember-insinuate org-open-at-point-global
+;;;;;; org-insert-link-global org-store-link orgtbl-mode turn-on-orgtbl
+;;;;;; org-run-like-in-org-mode turn-on-orgstruct++ turn-on-orgstruct
+;;;;;; orgstruct-mode org-global-cycle org-cycle org-mode) "org"
+;;;;;; "textmodes/org.el" (18463 9021))
;;; Generated autoloads from textmodes/org.el
(autoload (quote org-mode) "org" "\
`indent-relative', like TAB normally does. See the option
`org-cycle-emulate-tab' for details.
-- Special case: if point is the beginning of the buffer and there is no
- headline in line 1, this function will act as if called with prefix arg.
+- Special case: if point is at the beginning of the buffer and there is
+ no headline in line 1, this function will act as if called with prefix arg.
+ But only if also the variable `org-cycle-global-at-bob' is t.
\(fn &optional ARG)" t nil)
\(fn &optional ARG)" t nil)
+(autoload (quote orgstruct-mode) "org" "\
+Toggle the minor more `orgstruct-mode'.
+This mode is for using Org-mode structure commands in other modes.
+The following key behave as if Org-mode was active, if the cursor
+is on a headline, or on a plain list item (both in the definition
+of Org-mode).
+
+M-up Move entry/item up
+M-down Move entry/item down
+M-left Promote
+M-right Demote
+M-S-up Move entry/item up
+M-S-down Move entry/item down
+M-S-left Promote subtree
+M-S-right Demote subtree
+M-q Fill paragraph and items like in Org-mode
+C-c ^ Sort entries
+C-c - Cycle list bullet
+TAB Cycle item visibility
+M-RET Insert new heading/item
+S-M-RET Insert new TODO heading / Chekbox item
+C-c C-c Set tags / toggle checkbox
+
+\(fn &optional ARG)" t nil)
+
+(autoload (quote turn-on-orgstruct) "org" "\
+Unconditionally turn on `orgstruct-mode'.
+
+\(fn)" nil nil)
+
+(autoload (quote turn-on-orgstruct++) "org" "\
+Unconditionally turn on `orgstruct-mode', and force org-mode indentations.
+In addition to setting orgstruct-mode, this also exports all indentation and
+autofilling variables from org-mode into the buffer. Note that turning
+off orgstruct-mode will *not* remove these additional settings.
+
+\(fn)" nil nil)
+
+(autoload (quote org-run-like-in-org-mode) "org" "\
+Not documented
+
+\(fn CMD)" nil nil)
+
(autoload (quote turn-on-orgtbl) "org" "\
Unconditionally turn on `orgtbl-mode'.
(autoload (quote org-store-link) "org" "\
\\<org-mode-map>Store an org-link to the current location.
-This link can later be inserted into an org-buffer with
-\\[org-insert-link].
+This link is added to `org-stored-links' and can later be inserted
+into an org-buffer with \\[org-insert-link].
+
For some link types, a prefix arg is interpreted:
For links to usenet articles, arg negates `org-usenet-links-prefer-google'.
For file links, arg negates `org-context-in-file-links'.
\(fn ARG)" t nil)
+(autoload (quote org-insert-link-global) "org" "\
+Insert a link like Org-mode does.
+This command can be called in any mode to insert a link in Org-mode syntax.
+
+\(fn)" t nil)
+
+(autoload (quote org-open-at-point-global) "org" "\
+Follow a link like Org-mode does.
+This command can be called in any mode to follow a link that has
+Org-mode syntax.
+
+\(fn)" t nil)
+
+(autoload (quote org-remember-insinuate) "org" "\
+Setup remember.el for use wiht Org-mode.
+
+\(fn)" nil nil)
+
(autoload (quote org-remember-annotation) "org" "\
Return a link to the current location as an annotation for remember.el.
If you are using Org-mode files as target for data storage with
(autoload (quote org-remember-apply-template) "org" "\
Initialize *remember* buffer with template, invoke `org-mode'.
This function should be placed into `remember-mode-hook' and in fact requires
-to be run from that hook to fucntion properly.
+to be run from that hook to function properly.
\(fn &optional USE-CHAR SKIP-INTERACTIVE)" nil nil)
If there is an active region, make sure remember uses it as initial content
of the remember buffer.
-\(fn)" t nil)
+When called interactively with a `C-u' prefix argument GOTO, don't remember
+anything, just go to the file/headline where the selected template usually
+stores its notes. With a double prefix arg `C-u C-u', go to the last
+note stored by remember.
+
+Lisp programs can set ORG-FORCE-REMEMBER-TEMPLATE-CHAR to a character
+associated with a template in `org-remember-templates'.
+
+\(fn &optional GOTO ORG-FORCE-REMEMBER-TEMPLATE-CHAR)" t nil)
(autoload (quote org-remember-handler) "org" "\
Store stuff from remember.el into an org file.
Key Cursor position Note gets inserted
-----------------------------------------------------------------------------
-RET buffer-start as level 2 heading at end of file
+RET buffer-start as level 1 heading at end of file
RET on headline as sublevel of the heading at cursor
RET no heading at cursor position, level taken from context.
Or use prefix arg to specify level manually.
So the fastest way to store the note is to press RET RET to append it to
the default file. This way your current train of thought is not
-interrupted, in accordance with the principles of remember.el. But with
-little extra effort, you can push it directly to the correct location.
+interrupted, in accordance with the principles of remember.el.
+You can also get the fast execution without prompting by using
+C-u C-c C-c to exit the remember buffer. See also the variable
+`org-remember-store-without-prompt'.
Before being stored away, the function ensures that the text has a
headline, i.e. a first line that starts with a \"*\". If not, a headline
\(fn)" nil nil)
+(autoload (quote org-agenda-to-appt) "org" "\
+Activate appointments found in `org-agenda-files'.
+With a \\[universal-argument] prefix, refresh the list of
+appointements.
+
+If FILTER is t, interactively prompt the user for a regular
+expression, and filter out entries that don't match it.
+
+If FILTER is a string, use this string as a regular expression
+for filtering entries out.
+
+FILTER can also be an alist with the car of each cell being
+either 'headline or 'category. For example:
+
+ '((headline \"IMPORTANT\")
+ (category \"Work\"))
+
+will only add headlines containing IMPORTANT or headlines
+belonging to the \"Work\" category.
+
+\(fn &optional REFRESH FILTER)" t nil)
+
(autoload (quote org-agenda) "org" "\
Dispatch agenda commands to collect entries to the agenda buffer.
-Prompts for a character to select a command. Any prefix arg will be passed
+Prompts for a command to execute. Any prefix arg will be passed
on to the selected command. The default selections are:
-g
+
a Call `org-agenda-list' to display the agenda for current day or week.
t Call `org-todo-list' to display the global todo list.
T Call `org-todo-list' to display the global todo list, select only
m Call `org-tags-view' to display headlines with tags matching
a condition (the user is prompted for the condition).
M Like `m', but select only TODO entries, no ordinary headlines.
-l Create a timeeline for the current buffer.
+L Create a timeline for the current buffer.
+e Export views to associated files.
More commands can be added by configuring the variable
`org-agenda-custom-commands'. In particular, specific tags and TODO keyword
searches can be pre-defined in this way.
If the current buffer is in Org-mode and visiting a file, you can also
-first press `1' to indicate that the agenda should be temporarily (until the
-next use of \\[org-agenda]) restricted to the current file.
+first press `<' once to indicate that the agenda should be temporarily
+\(until the next use of \\[org-agenda]) restricted to the current file.
+Pressing `<' twice means to restrict to the current subtree or region
+\(if active).
-\(fn ARG)" t nil)
+\(fn ARG &optional KEYS RESTRICTION)" t nil)
(autoload (quote org-batch-agenda) "org" "\
-Run an agenda command in batch mode, send result to STDOUT.
-CMD-KEY is a string that is also a key in `org-agenda-custom-commands'.
+Run an agenda command in batch mode and send the result to STDOUT.
+If CMD-KEY is a string of length 1, it is used as a key in
+`org-agenda-custom-commands' and triggers this command. If it is a
+longer string it is used as a tags/todo match string.
Paramters are alternating variable names and values that will be bound
before running the agenda command.
\(fn CMD-KEY &rest PARAMETERS)" nil (quote macro))
+(autoload (quote org-batch-agenda-csv) "org" "\
+Run an agenda command in batch mode and send the result to STDOUT.
+If CMD-KEY is a string of length 1, it is used as a key in
+`org-agenda-custom-commands' and triggers this command. If it is a
+longer string it is used as a tags/todo match string.
+Paramters are alternating variable names and values that will be bound
+before running the agenda command.
+
+The output gives a line for each selected agenda item. Each
+item is a list of comma-separated values, like this:
+
+category,head,type,todo,tags,date,time,extra,priority-l,priority-n
+
+category The category of the item
+head The headline, without TODO kwd, TAGS and PRIORITY
+type The type of the agenda entry, can be
+ todo selected in TODO match
+ tagsmatch selected in tags match
+ diary imported from diary
+ deadline a deadline on given date
+ scheduled scheduled on given date
+ timestamp entry has timestamp on given date
+ closed entry was closed on given date
+ upcoming-deadline warning about deadline
+ past-scheduled forwarded scheduled item
+ block entry has date block including g. date
+todo The todo keyword, if any
+tags All tags including inherited ones, separated by colons
+date The relevant date, like 2007-2-14
+time The time, like 15:00-16:50
+extra Sting with extra planning info
+priority-l The priority letter if any was given
+priority-n The computed numerical priority
+agenda-day The day in the agenda where this is listed
+
+\(fn CMD-KEY &rest PARAMETERS)" nil (quote macro))
+
+(autoload (quote org-store-agenda-views) "org" "\
+Not documented
+
+\(fn &rest PARAMETERS)" t nil)
+
+(autoload (quote org-batch-store-agenda-views) "org" "\
+Run all custom agenda commands that have a file argument.
+
+\(fn &rest PARAMETERS)" nil (quote macro))
+
(autoload (quote org-cycle-agenda-files) "org" "\
Cycle through the files in `org-agenda-files'.
If the current buffer visits an agenda file, find the next one in the list.
\(fn)" t nil)
(autoload (quote org-agenda-list) "org" "\
-Produce a weekly view from all files in variable `org-agenda-files'.
-The view will be for the current week, but from the overview buffer you
-will be able to go to other weeks.
-With one \\[universal-argument] prefix argument INCLUDE-ALL, all unfinished TODO items will
-also be shown, under the current date.
-With two \\[universal-argument] prefix argument INCLUDE-ALL, all TODO entries marked DONE
-on the days are also shown. See the variable `org-log-done' for how
-to turn on logging.
+Produce a daily/weekly view from all files in variable `org-agenda-files'.
+The view will be for the current day or week, but from the overview buffer
+you will be able to go to other days/weeks.
+
+With one \\[universal-argument] prefix argument INCLUDE-ALL,
+all unfinished TODO items will also be shown, before the agenda.
+This feature is considered obsolete, please use the TODO list or a block
+agenda instead.
+
+With a numeric prefix argument in an interactive call, the agenda will
+span INCLUDE-ALL days. Lisp programs should instead specify NDAYS to change
+the number of days. NDAYS defaults to `org-agenda-ndays'.
+
START-DAY defaults to TODAY, or to the most recent match for the weekday
given in `org-agenda-start-on-weekday'.
-NDAYS defaults to `org-agenda-ndays'.
\(fn &optional INCLUDE-ALL START-DAY NDAYS)" t nil)
+(autoload (quote org-search-view) "org" "\
+Show all entries that contain words or regular expressions.
+If the first character of the search string is an asterisks,
+search only the headlines.
+
+The search string is broken into \"words\" by splitting at whitespace.
+The individual words are then interpreted as a boolean expression with
+logical AND. Words prefixed with a minus must not occur in the entry.
+Words without a prefix or prefixed with a plus must occur in the entry.
+Matching is case-insensitive and the words are enclosed by word delimiters.
+
+Words enclosed by curly braces are interpreted as regular expressions
+that must or must not match in the entry.
+
+This command searches the agenda files, and in addition the files listed
+in `org-agenda-text-search-extra-files'.
+
+\(fn &optional ARG STRING)" t nil)
+
(autoload (quote org-todo-list) "org" "\
Show all TODO entries from all agenda file in a single list.
The prefix arg can be used to select a specific TODO keyword and limit
the list to these. When using \\[universal-argument], you will be prompted
for a keyword. A numeric prefix directly selects the Nth keyword in
-`org-todo-keywords'.
+`org-todo-keywords-1'.
\(fn ARG)" t nil)
\(fn &optional TODO-ONLY MATCH)" t nil)
+(autoload (quote org-agenda-list-stuck-projects) "org" "\
+Create agenda view for projects that are stuck.
+Stuck projects are project that have no next actions. For the definitions
+of what a project is and how to check if it stuck, customize the variable
+`org-stuck-projects'.
+MATCH is being ignored.
+
+\(fn &rest IGNORE)" t nil)
+
(autoload (quote org-diary) "org" "\
Return diary information from org-files.
This function can be used in a \"sexp\" diary entry in the Emacs calendar.
date range matching the selected date. Deadlines will
also be listed, on the expiration day.
+ :sexp List entries resulting from diary-like sexps.
+
:deadline List any deadlines past due, or due within
`org-deadline-warning-days'. The listing occurs only
in the diary for *today*, not at any other date. If
&%%(org-diary)
If you don't give any arguments (as in the example above), the default
-arguments (:deadline :scheduled :timestamp) are used. So the example above may
-also be written as
+arguments (:deadline :scheduled :timestamp :sexp) are used.
+So the example above may also be written as
- &%%(org-diary :deadline :timestamp :scheduled)
+ &%%(org-diary :deadline :timestamp :sexp :scheduled)
The function expects the lisp variables `entry' and `date' to be provided
by the caller, because this is how the calendar works. Don't use this
\(fn)" t nil)
+;;;***
+\f
+;;;### (autoloads (org-export-as-latex org-export-region-as-latex
+;;;;;; org-replace-region-by-latex org-export-as-latex-to-buffer
+;;;;;; org-export-as-latex-batch) "org-export-latex" "textmodes/org-export-latex.el"
+;;;;;; (18427 8817))
+;;; Generated autoloads from textmodes/org-export-latex.el
+
+(autoload (quote org-export-as-latex-batch) "org-export-latex" "\
+Call `org-export-as-latex', may be used in batch processing as
+emacs --batch
+ --load=$HOME/lib/emacs/org.el
+ --eval \"(setq org-export-headline-levels 2)\"
+ --visit=MyFile --funcall org-export-as-latex-batch
+
+\(fn)" nil nil)
+
+(autoload (quote org-export-as-latex-to-buffer) "org-export-latex" "\
+Call `org-exort-as-latex` with output to a temporary buffer.
+No file is created. The prefix ARG is passed through to `org-export-as-latex'.
+
+\(fn ARG)" t nil)
+
+(autoload (quote org-replace-region-by-latex) "org-export-latex" "\
+Replace the region from BEG to END with its LaTeX export.
+It assumes the region has `org-mode' syntax, and then convert it to
+LaTeX. This can be used in any buffer. For example, you could
+write an itemized list in `org-mode' syntax in an LaTeX buffer and
+then use this command to convert it.
+
+\(fn BEG END)" t nil)
+
+(autoload (quote org-export-region-as-latex) "org-export-latex" "\
+Convert region from BEG to END in `org-mode' buffer to LaTeX.
+If prefix arg BODY-ONLY is set, omit file header, footer, and table of
+contents, and only produce the region of converted text, useful for
+cut-and-paste operations.
+If BUFFER is a buffer or a string, use/create that buffer as a target
+of the converted LaTeX. If BUFFER is the symbol `string', return the
+produced LaTeX as a string and leave not buffer behind. For example,
+a Lisp program could call this function in the following way:
+
+ (setq latex (org-export-region-as-latex beg end t 'string))
+
+When called interactively, the output buffer is selected, and shown
+in a window. A non-interactive call will only retunr the buffer.
+
+\(fn BEG END &optional BODY-ONLY BUFFER)" t nil)
+
+(autoload (quote org-export-as-latex) "org-export-latex" "\
+Export current buffer to a LaTeX file.
+If there is an active region, export only the region. The prefix
+ARG specifies how many levels of the outline should become
+headlines. The default is 3. Lower levels will be exported
+depending on `org-export-latex-low-levels'. The default is to
+convert them as description lists. When HIDDEN is non-nil, don't
+display the LaTeX buffer. EXT-PLIST is a property list with
+external parameters overriding org-mode's default settings, but
+still inferior to file-local settings. When TO-BUFFER is
+non-nil, create a buffer with that name and export to that
+buffer. If TO-BUFFER is the symbol `string', don't leave any
+buffer behind but just return the resulting LaTeX as a string.
+When BODY-ONLY is set, don't produce the file header and footer,
+simply return the content of \begin{document}...\end{document},
+without even the \begin{document} and \end{document} commands.
+when PUB-DIR is set, use this as the publishing directory.
+
+\(fn ARG &optional HIDDEN EXT-PLIST TO-BUFFER BODY-ONLY PUB-DIR)" t nil)
+
+;;;***
+\f
+;;;### (autoloads (org-irc-store-link) "org-irc" "textmodes/org-irc.el"
+;;;;;; (18427 8818))
+;;; Generated autoloads from textmodes/org-irc.el
+
+(autoload (quote org-irc-store-link) "org-irc" "\
+Dispatch to the appropreate function to store a link to
+something IRC related
+
+\(fn)" nil nil)
+
+;;;***
+\f
+;;;### (autoloads (org-publish-current-project org-publish-current-file
+;;;;;; org-publish-all org-publish) "org-publish" "textmodes/org-publish.el"
+;;;;;; (18427 8818))
+;;; Generated autoloads from textmodes/org-publish.el
+
+(autoload (quote org-publish) "org-publish" "\
+Publish PROJECT.
+
+\(fn PROJECT &optional FORCE)" t nil)
+
+(autoload (quote org-publish-all) "org-publish" "\
+Publish all projects.
+With prefix argument, force publish all files.
+
+\(fn &optional FORCE)" t nil)
+
+(autoload (quote org-publish-current-file) "org-publish" "\
+Publish the current file.
+With prefix argument, force publish the file.
+
+\(fn &optional FORCE)" t nil)
+
+(autoload (quote org-publish-current-project) "org-publish" "\
+Publish the project associated with the current file.
+With a prefix argument, force publishing of all files in
+the project.
+
+\(fn &optional FORCE)" t nil)
+
;;;***
\f
;;;### (autoloads (outline-minor-mode outline-mode) "outline" "outline.el"
;;;***
\f
-;;;### (autoloads nil "paragraphs" "textmodes/paragraphs.el" (18310
-;;;;;; 14605))
+;;;### (autoloads nil "paragraphs" "textmodes/paragraphs.el" (18432
+;;;;;; 17907))
;;; Generated autoloads from textmodes/paragraphs.el
(put 'paragraph-start 'safe-local-variable 'stringp)
(put 'paragraph-separate 'safe-local-variable 'stringp)
;;;***
\f
;;;### (autoloads (pgg-gpg-symmetric-key-p) "pgg-gpg" "pgg-gpg.el"
-;;;;;; (18310 14576))
+;;;;;; (18580 44915))
;;; Generated autoloads from pgg-gpg.el
(autoload (quote pgg-gpg-symmetric-key-p) "pgg-gpg" "\
;;;;;; ps-spool-region ps-spool-buffer-with-faces ps-spool-buffer
;;;;;; ps-print-region-with-faces ps-print-region ps-print-buffer-with-faces
;;;;;; ps-print-buffer ps-print-customize ps-print-color-p ps-paper-type
-;;;;;; ps-page-dimensions-database) "ps-print" "ps-print.el" (18310
-;;;;;; 14577))
+;;;;;; ps-page-dimensions-database) "ps-print" "ps-print.el" (18419
+;;;;;; 51077))
;;; Generated autoloads from ps-print.el
(defvar ps-page-dimensions-database (list (list (quote a4) (/ (* 72 21.0) 2.54) (/ (* 72 29.7) 2.54) "A4") (list (quote a3) (/ (* 72 29.7) 2.54) (/ (* 72 42.0) 2.54) "A3") (list (quote letter) (* 72 8.5) (* 72 11.0) "Letter") (list (quote legal) (* 72 8.5) (* 72 14.0) "Legal") (list (quote letter-small) (* 72 7.68) (* 72 10.16) "LetterSmall") (list (quote tabloid) (* 72 11.0) (* 72 17.0) "Tabloid") (list (quote ledger) (* 72 17.0) (* 72 11.0) "Ledger") (list (quote statement) (* 72 5.5) (* 72 8.5) "Statement") (list (quote executive) (* 72 7.5) (* 72 10.0) "Executive") (list (quote a4small) (* 72 7.47) (* 72 10.85) "A4Small") (list (quote b4) (* 72 10.125) (* 72 14.33) "B4") (list (quote b5) (* 72 7.16) (* 72 10.125) "B5")) "\
;;;***
\f
;;;### (autoloads (jython-mode python-mode run-python) "python" "progmodes/python.el"
-;;;;;; (18326 18336))
+;;;;;; (18612 9510))
;;; Generated autoloads from progmodes/python.el
(add-to-list (quote interpreter-mode-alist) (quote ("jython" . jython-mode)))
;;;***
\f
;;;### (autoloads (shell shell-dumb-shell-regexp) "shell" "shell.el"
-;;;;;; (18376 17161))
+;;;;;; (18567 43470))
;;; Generated autoloads from shell.el
(defvar shell-dumb-shell-regexp "cmd\\(proxy\\)?\\.exe" "\
;;;***
\f
-;;;### (autoloads nil "simple" "simple.el" (18389 59148))
+;;;### (autoloads nil "simple" "simple.el" (18593 55294))
;;; Generated autoloads from simple.el
(put 'fill-prefix 'safe-local-variable 'string-or-null-p)
;;;***
\f
;;;### (autoloads (smerge-mode smerge-ediff) "smerge-mode" "smerge-mode.el"
-;;;;;; (18310 14577))
+;;;;;; (18469 40408))
;;; Generated autoloads from smerge-mode.el
(autoload (quote smerge-ediff) "smerge-mode" "\
;;;***
\f
-;;;### (autoloads (solitaire) "solitaire" "play/solitaire.el" (18310
-;;;;;; 14597))
+;;;### (autoloads (solitaire) "solitaire" "play/solitaire.el" (18612
+;;;;;; 9510))
;;; Generated autoloads from play/solitaire.el
(autoload (quote solitaire) "solitaire" "\
Undo moves using \\[solitaire-undo].
Check for possible moves using \\[solitaire-do-check].
\(The variable `solitaire-auto-eval' controls whether to automatically
-check after each move or undo)
+check after each move or undo.)
What is Solitaire?
;;;***
\f
;;;### (autoloads (speedbar-get-focus speedbar-frame-mode) "speedbar"
-;;;;;; "speedbar.el" (18310 14577))
+;;;;;; "speedbar.el" (18612 9509))
;;; Generated autoloads from speedbar.el
(defalias (quote speedbar) (quote speedbar-frame-mode))
;;;***
\f
-;;;### (autoloads (locate-library) "subr" "subr.el" (18388 4644))
+;;;### (autoloads (locate-library) "subr" "subr.el" (18621 22670))
;;; Generated autoloads from subr.el
(autoload (quote locate-library) "subr" "\
If the optional third arg PATH is specified, that list of directories
is used instead of `load-path'.
-When called from a program, the file name is normaly returned as a
+When called from a program, the file name is normally returned as a
string. When run interactively, the argument INTERACTIVE-CALL is t,
and the file name is displayed in the echo area.
;;;***
\f
-;;;### (autoloads (tar-mode) "tar-mode" "tar-mode.el" (18310 14577))
+;;;### (autoloads (tar-mode) "tar-mode" "tar-mode.el" (18490 63050))
;;; Generated autoloads from tar-mode.el
(autoload (quote tar-mode) "tar-mode" "\
;;;;;; tex-start-commands tex-start-options slitex-run-command latex-run-command
;;;;;; tex-run-command tex-offer-save tex-main-file tex-first-line-header-regexp
;;;;;; tex-directory tex-shell-file-name) "tex-mode" "textmodes/tex-mode.el"
-;;;;;; (18310 14607))
+;;;;;; (18570 7790))
;;; Generated autoloads from textmodes/tex-mode.el
(defvar tex-shell-file-name nil "\
\f
;;;### (autoloads (tool-bar-local-item-from-menu tool-bar-add-item-from-menu
;;;;;; tool-bar-local-item tool-bar-add-item) "tool-bar" "tool-bar.el"
-;;;;;; (18310 14578))
+;;;;;; (18612 9509))
;;; Generated autoloads from tool-bar.el
(put (quote tool-bar-mode) (quote standard-value) (quote (t)))
Info node `(elisp)Tool Bar'. Items are added from left to right.
ICON is the base name of a file containing the image to use. The
-function will first try to use low-color/ICON.xpm if display-color-cells
+function will first try to use low-color/ICON.xpm if `display-color-cells'
is less or equal to 256, then ICON.xpm, then ICON.pbm, and finally
ICON.xbm, using `find-image'.
;;;***
\f
;;;### (autoloads (tpu-edt-on tpu-edt-mode) "tpu-edt" "emulation/tpu-edt.el"
-;;;;;; (18310 14582))
+;;;;;; (18612 9509))
;;; Generated autoloads from emulation/tpu-edt.el
(defvar tpu-edt-mode nil "\
;;;### (autoloads (tramp-unload-tramp tramp-completion-handle-file-name-completion
;;;;;; tramp-completion-handle-file-name-all-completions tramp-unload-file-name-handlers
;;;;;; tramp-file-name-handler tramp-completion-file-name-regexp
-;;;;;; tramp-file-name-regexp) "tramp" "net/tramp.el" (18355 36599))
+;;;;;; tramp-file-name-regexp) "tramp" "net/tramp.el" (18574 8385))
;;; Generated autoloads from net/tramp.el
(defvar tramp-unified-filenames (not (featurep (quote xemacs))) "\
;;;***
\f
;;;### (autoloads (url-register-auth-scheme url-get-authentication)
-;;;;;; "url-auth" "url/url-auth.el" (18377 44624))
+;;;;;; "url-auth" "url/url-auth.el" (18417 24432))
;;; Generated autoloads from url/url-auth.el
(autoload (quote url-get-authentication) "url-auth" "\
;;;***
\f
;;;### (autoloads (url-http-options url-http-file-attributes url-http-file-exists-p
-;;;;;; url-http) "url-http" "url/url-http.el" (18310 14608))
+;;;;;; url-http) "url-http" "url/url-http.el" (18621 22671))
;;; Generated autoloads from url/url-http.el
(autoload (quote url-http) "url-http" "\
(defconst url-https-asynchronous-p t "\
HTTPS retrievals are asynchronous.")
+ (autoload 'url-default-expander "url-expand")
-(defalias (quote url-https-expand-file-name) (quote url-http-expand-file-name))
+(defalias (quote url-https-expand-file-name) (quote url-default-expander))
(autoload 'url-https "url-http")
(autoload 'url-https-file-exists-p "url-http")
(autoload 'url-https-file-readable-p "url-http")
;;;;;; vc-directory vc-merge vc-insert-headers vc-version-other-window
;;;;;; vc-diff vc-register vc-next-action vc-do-command edit-vc-file
;;;;;; with-vc-file vc-branch-part vc-trunk-p vc-before-checkin-hook
-;;;;;; vc-checkin-hook vc-checkout-hook) "vc" "vc.el" (18342 38263))
+;;;;;; vc-checkin-hook vc-checkout-hook) "vc" "vc.el" (18414 39572))
;;; Generated autoloads from vc.el
(defvar vc-checkout-hook nil "\
;;;***
\f
-;;;### (autoloads nil "vc-hg" "vc-hg.el" (18310 14578))
+;;;### (autoloads nil "vc-hg" "vc-hg.el" (18479 55600))
;;; Generated autoloads from vc-hg.el
(defun vc-hg-registered (file)
"Return non-nil if FILE is registered with hg."
;;;***
\f
;;;### (autoloads (woman-find-file woman-dired-find-file woman) "woman"
-;;;;;; "woman.el" (18316 51172))
+;;;;;; "woman.el" (18430 52623))
;;; Generated autoloads from woman.el
(autoload (quote woman) "woman" "\
;;;;;; "register.el" "replace.el" "rfn-eshadow.el" "s-region.el"
;;;;;; "saveplace.el" "sb-image.el" "scroll-bar.el" "select.el"
;;;;;; "soundex.el" "startup.el" "subdirs.el" "tempo.el" "textmodes/bib-mode.el"
-;;;;;; "textmodes/makeinfo.el" "textmodes/page-ext.el" "textmodes/page.el"
-;;;;;; "textmodes/refbib.el" "textmodes/refer.el" "textmodes/reftex-auc.el"
-;;;;;; "textmodes/reftex-dcr.el" "textmodes/reftex-ref.el" "textmodes/reftex-sel.el"
-;;;;;; "textmodes/reftex-toc.el" "textmodes/texnfo-upd.el" "textmodes/text-mode.el"
-;;;;;; "timezone.el" "tooltip.el" "tree-widget.el" "uniquify.el"
-;;;;;; "url/url-about.el" "url/url-cookie.el" "url/url-dired.el"
-;;;;;; "url/url-expand.el" "url/url-ftp.el" "url/url-history.el"
-;;;;;; "url/url-imap.el" "url/url-methods.el" "url/url-nfs.el" "url/url-proxy.el"
-;;;;;; "url/url-vars.el" "url/vc-dav.el" "vc-hooks.el" "vcursor.el"
-;;;;;; "version.el" "vms-patch.el" "vmsproc.el" "vt-control.el"
-;;;;;; "vt100-led.el" "w32-fns.el" "w32-vars.el" "widget.el" "window.el"
-;;;;;; "x-dnd.el") (18410 21129 646372))
+;;;;;; "textmodes/makeinfo.el" "textmodes/org-mac-message.el" "textmodes/org-mouse.el"
+;;;;;; "textmodes/page-ext.el" "textmodes/page.el" "textmodes/refbib.el"
+;;;;;; "textmodes/refer.el" "textmodes/reftex-auc.el" "textmodes/reftex-dcr.el"
+;;;;;; "textmodes/reftex-ref.el" "textmodes/reftex-sel.el" "textmodes/reftex-toc.el"
+;;;;;; "textmodes/texnfo-upd.el" "textmodes/text-mode.el" "timezone.el"
+;;;;;; "tooltip.el" "tree-widget.el" "uniquify.el" "url/url-about.el"
+;;;;;; "url/url-cookie.el" "url/url-dired.el" "url/url-expand.el"
+;;;;;; "url/url-ftp.el" "url/url-history.el" "url/url-imap.el" "url/url-methods.el"
+;;;;;; "url/url-nfs.el" "url/url-proxy.el" "url/url-vars.el" "url/vc-dav.el"
+;;;;;; "vc-hooks.el" "vcursor.el" "version.el" "vms-patch.el" "vmsproc.el"
+;;;;;; "vt-control.el" "vt100-led.el" "w32-fns.el" "w32-vars.el"
+;;;;;; "widget.el" "window.el" "x-dnd.el") (18625 23607 152932))
;;;***
\f
;;;### (autoloads (change-log-merge add-log-current-defun change-log-mode
;;;;;; add-change-log-entry-other-window add-change-log-entry find-change-log
;;;;;; prompt-for-change-log-name add-log-mailing-address add-log-full-name
-;;;;;; add-log-current-defun-function) "add-log" "add-log.el" (18336
-;;;;;; 60192))
+;;;;;; add-log-current-defun-function) "add-log" "add-log.el" (18419
+;;;;;; 63244))
;;; Generated autoloads from add-log.el
(defvar add-log-current-defun-function nil "\
\f
;;;### (autoloads (batch-update-autoloads update-directory-autoloads
;;;;;; update-file-autoloads) "autoload" "emacs-lisp/autoload.el"
-;;;;;; (18310 14580))
+;;;;;; (18430 50673))
;;; Generated autoloads from emacs-lisp/autoload.el
(autoload (quote update-file-autoloads) "autoload" "\
;;;;;; batch-byte-compile-if-not-done display-call-tree byte-compile
;;;;;; compile-defun byte-compile-file byte-recompile-directory
;;;;;; byte-force-recompile byte-compile-warnings-safe-p) "bytecomp"
-;;;;;; "emacs-lisp/bytecomp.el" (18310 14580))
+;;;;;; "emacs-lisp/bytecomp.el" (18593 55295))
;;; Generated autoloads from emacs-lisp/bytecomp.el
(put 'byte-compile-dynamic 'safe-local-variable 'booleanp)
(put 'byte-compile-disable-print-circle 'safe-local-variable 'booleanp)
(autoload (quote byte-compile-file) "bytecomp" "\
Compile a file of Lisp code named FILENAME into a file of byte code.
The output file's name is generated by passing FILENAME to the
-`byte-compile-dest-file' function (which see).
+function `byte-compile-dest-file' (which see).
With prefix arg (noninteractively: 2nd arg), LOAD the file after compiling.
The value is non-nil if there were no errors, nil if errors.
;;;***
\f
;;;### (autoloads (list-yahrzeit-dates) "cal-hebrew" "calendar/cal-hebrew.el"
-;;;;;; (18310 14579))
+;;;;;; (18489 51007))
;;; Generated autoloads from calendar/cal-hebrew.el
(autoload (quote list-yahrzeit-dates) "cal-hebrew" "\
;;;### (autoloads (defmath calc-embedded-activate calc-embedded calc-grab-rectangle
;;;;;; calc-grab-region full-calc-keypad calc-keypad calc-eval quick-calc
;;;;;; full-calc calc calc-dispatch calc-settings-file) "calc" "calc/calc.el"
-;;;;;; (18310 14579))
+;;;;;; (18417 40519))
;;; Generated autoloads from calc/calc.el
(defvar calc-settings-file (convert-standard-filename "~/.calc.el") "\
;;;;;; mark-holidays-in-calendar view-calendar-holidays-initially
;;;;;; calendar-remove-frame-by-deleting mark-diary-entries-in-calendar
;;;;;; view-diary-entries-initially calendar-offset) "calendar"
-;;;;;; "calendar/calendar.el" (18310 14580))
+;;;;;; "calendar/calendar.el" (18593 55294))
;;; Generated autoloads from calendar/calendar.el
(defvar calendar-offset 0 "\
;;;***
\f
;;;### (autoloads (c-guess-basic-syntax) "cc-engine" "progmodes/cc-engine.el"
-;;;;;; (18368 29740))
+;;;;;; (18524 49166))
;;; Generated autoloads from progmodes/cc-engine.el
(autoload (quote c-guess-basic-syntax) "cc-engine" "\
\f
;;;### (autoloads (pike-mode idl-mode java-mode objc-mode c++-mode
;;;;;; c-mode c-initialize-cc-mode) "cc-mode" "progmodes/cc-mode.el"
-;;;;;; (18383 1613))
+;;;;;; (18488 2751))
;;; Generated autoloads from progmodes/cc-mode.el
(autoload (quote c-initialize-cc-mode) "cc-mode" "\
;;;***
\f
;;;### (autoloads (c-set-offset c-add-style c-set-style) "cc-styles"
-;;;;;; "progmodes/cc-styles.el" (18368 9297))
+;;;;;; "progmodes/cc-styles.el" (18578 10872))
;;; Generated autoloads from progmodes/cc-styles.el
(autoload (quote c-set-style) "cc-styles" "\
;;;### (autoloads (comint-redirect-results-list-from-process comint-redirect-results-list
;;;;;; comint-redirect-send-command-to-process comint-redirect-send-command
;;;;;; comint-run make-comint make-comint-in-buffer) "comint" "comint.el"
-;;;;;; (18326 18335))
+;;;;;; (18612 36171))
;;; Generated autoloads from comint.el
(defvar comint-output-filter-functions (quote (comint-postoutput-scroll-to-bottom comint-watch-for-password-prompt)) "\
;;;;;; compilation-shell-minor-mode compilation-mode compilation-start
;;;;;; compile compilation-disable-input compile-command compilation-search-path
;;;;;; compilation-ask-about-save compilation-window-height compilation-mode-hook)
-;;;;;; "compile" "progmodes/compile.el" (18368 9297))
+;;;;;; "compile" "progmodes/compile.el" (18574 9600))
;;; Generated autoloads from progmodes/compile.el
(defvar compilation-mode-hook nil "\
;;;;;; customize-mode customize customize-save-variable customize-set-variable
;;;;;; customize-set-value custom-menu-sort-alphabetically custom-buffer-sort-alphabetically
;;;;;; custom-browse-sort-alphabetically) "cus-edit" "cus-edit.el"
-;;;;;; (18310 14567))
+;;;;;; (18580 52460))
;;; Generated autoloads from cus-edit.el
(defvar custom-browse-sort-alphabetically nil "\
;;;***
\f
;;;### (autoloads (dabbrev-expand dabbrev-completion) "dabbrev" "dabbrev.el"
-;;;;;; (18310 14568))
+;;;;;; (18611 12227))
;;; Generated autoloads from dabbrev.el
(define-key esc-map "/" 'dabbrev-expand)
(define-key esc-map [?\C-/] 'dabbrev-completion)
;;;### (autoloads (desktop-revert desktop-save-in-desktop-dir desktop-change-dir
;;;;;; desktop-load-default desktop-read desktop-remove desktop-save
;;;;;; desktop-clear desktop-locals-to-save desktop-save-mode) "desktop"
-;;;;;; "desktop.el" (18383 1604))
+;;;;;; "desktop.el" (18597 43990))
;;; Generated autoloads from desktop.el
(defvar desktop-save-mode nil "\
;;;***
\f
;;;### (autoloads (diary-mode diary-mail-entries diary) "diary-lib"
-;;;;;; "calendar/diary-lib.el" (18310 14580))
+;;;;;; "calendar/diary-lib.el" (18593 55294))
;;; Generated autoloads from calendar/diary-lib.el
(autoload (quote diary) "diary-lib" "\
;;;***
\f
;;;### (autoloads (diff-minor-mode diff-mode) "diff-mode" "diff-mode.el"
-;;;;;; (18408 28171))
+;;;;;; (18449 15659))
;;; Generated autoloads from diff-mode.el
(autoload (quote diff-mode) "diff-mode" "\
;;;;;; dired dired-copy-preserve-time dired-dwim-target dired-keep-marker-symlink
;;;;;; dired-keep-marker-hardlink dired-keep-marker-copy dired-keep-marker-rename
;;;;;; dired-trivial-filenames dired-ls-F-marks-symlinks dired-listing-switches)
-;;;;;; "dired" "dired.el" (18397 19038))
+;;;;;; "dired" "dired.el" (18425 14914))
;;; Generated autoloads from dired.el
(defvar dired-listing-switches "-al" "\
;;;;;; dired-run-shell-command dired-do-shell-command dired-clean-directory
;;;;;; dired-do-print dired-do-touch dired-do-chown dired-do-chgrp
;;;;;; dired-do-chmod dired-compare-directories dired-backup-diff
-;;;;;; dired-diff) "dired-aux" "dired-aux.el" (18310 14568))
+;;;;;; dired-diff) "dired-aux" "dired-aux.el" (18568 43717))
;;; Generated autoloads from dired-aux.el
(autoload (quote dired-diff) "dired-aux" "\
;;;***
\f
;;;### (autoloads (dired-do-relsymlink dired-jump) "dired-x" "dired-x.el"
-;;;;;; (18310 14568))
+;;;;;; (18611 12215))
;;; Generated autoloads from dired-x.el
(autoload (quote dired-jump) "dired-x" "\
\f
;;;### (autoloads (edebug-all-forms edebug-all-defs edebug-eval-top-level-form
;;;;;; edebug-basic-spec edebug-all-forms edebug-all-defs) "edebug"
-;;;;;; "emacs-lisp/edebug.el" (18368 9295))
+;;;;;; "emacs-lisp/edebug.el" (18615 8002))
;;; Generated autoloads from emacs-lisp/edebug.el
(defvar edebug-all-defs nil "\
;;;***
\f
;;;### (autoloads (edt-emulation-on edt-set-scroll-margins) "edt"
-;;;;;; "emulation/edt.el" (18310 14582))
+;;;;;; "emulation/edt.el" (18601 51444))
;;; Generated autoloads from emulation/edt.el
(autoload (quote edt-set-scroll-margins) "edt" "\
;;;***
\f
;;;### (autoloads (enriched-decode enriched-encode enriched-mode)
-;;;;;; "enriched" "textmodes/enriched.el" (18310 14604))
+;;;;;; "enriched" "textmodes/enriched.el" (18568 43591))
;;; Generated autoloads from textmodes/enriched.el
(autoload (quote enriched-mode) "enriched" "\
;;;***
\f
-;;;### (autoloads (f90-mode) "f90" "progmodes/f90.el" (18310 14599))
+;;;### (autoloads (f90-mode) "f90" "progmodes/f90.el" (18593 55295))
;;; Generated autoloads from progmodes/f90.el
(autoload (quote f90-mode) "f90" "\
;;;;;; facemenu-remove-all facemenu-remove-face-props facemenu-set-read-only
;;;;;; facemenu-set-intangible facemenu-set-invisible facemenu-set-face-from-menu
;;;;;; facemenu-set-background facemenu-set-foreground facemenu-set-face)
-;;;;;; "facemenu" "facemenu.el" (18310 14569))
+;;;;;; "facemenu" "facemenu.el" (18612 9509))
;;; Generated autoloads from facemenu.el
(define-key global-map "\M-o" 'facemenu-keymap)
(autoload 'facemenu-keymap "facemenu" "Keymap for face-changing commands." t 'keymap)
;;;***
\f
-;;;### (autoloads nil "fill" "textmodes/fill.el" (18377 44624))
+;;;### (autoloads nil "fill" "textmodes/fill.el" (18612 9510))
;;; Generated autoloads from textmodes/fill.el
(put 'colon-double-space 'safe-local-variable 'booleanp)
\f
;;;### (autoloads (find-grep-dired find-name-dired find-dired find-name-arg
;;;;;; find-grep-options find-ls-subdir-switches find-ls-option)
-;;;;;; "find-dired" "find-dired.el" (18310 14569))
+;;;;;; "find-dired" "find-dired.el" (18418 29074))
;;; Generated autoloads from find-dired.el
(defvar find-ls-option (if (eq system-type (quote berkeley-unix)) (quote ("-ls" . "-gilsb")) (quote ("-exec ls -ld {} \\;" . "-ld"))) "\
;;;;;; find-variable find-variable-noselect find-function-other-frame
;;;;;; find-function-other-window find-function find-function-noselect
;;;;;; find-function-search-for-symbol find-library) "find-func"
-;;;;;; "emacs-lisp/find-func.el" (18310 14581))
+;;;;;; "emacs-lisp/find-func.el" (18597 43991))
;;; Generated autoloads from emacs-lisp/find-func.el
(autoload (quote find-library) "find-func" "\
;;;***
\f
;;;### (autoloads (finder-by-keyword finder-commentary finder-list-keywords)
-;;;;;; "finder" "finder.el" (18310 14569))
+;;;;;; "finder" "finder.el" (18593 55294))
;;; Generated autoloads from finder.el
(autoload (quote finder-list-keywords) "finder" "\
;;;***
\f
;;;### (autoloads (flymake-mode-off flymake-mode-on flymake-mode)
-;;;;;; "flymake" "progmodes/flymake.el" (18310 14600))
+;;;;;; "flymake" "progmodes/flymake.el" (18567 43650))
;;; Generated autoloads from progmodes/flymake.el
(autoload (quote flymake-mode) "flymake" "\
\f
;;;### (autoloads (flyspell-buffer flyspell-region flyspell-mode-off
;;;;;; turn-off-flyspell turn-on-flyspell flyspell-mode flyspell-prog-mode)
-;;;;;; "flyspell" "textmodes/flyspell.el" (18310 14604))
+;;;;;; "flyspell" "textmodes/flyspell.el" (18612 35635))
;;; Generated autoloads from textmodes/flyspell.el
(autoload (quote flyspell-prog-mode) "flyspell" "\
;;;***
\f
;;;### (autoloads (fortran-mode fortran-tab-mode-default) "fortran"
-;;;;;; "progmodes/fortran.el" (18310 14600))
+;;;;;; "progmodes/fortran.el" (18593 55295))
;;; Generated autoloads from progmodes/fortran.el
(defvar fortran-tab-mode-default nil "\
;;;***
\f
;;;### (autoloads (gdb-enable-debug gdb) "gdb-ui" "progmodes/gdb-ui.el"
-;;;;;; (18389 59107))
+;;;;;; (18612 9510))
;;; Generated autoloads from progmodes/gdb-ui.el
(autoload (quote gdb) "gdb-ui" "\
;;;***
\f
;;;### (autoloads (gnus-article-prepare-display) "gnus-art" "gnus/gnus-art.el"
-;;;;;; (18389 59107))
+;;;;;; (18490 24742))
;;; Generated autoloads from gnus/gnus-art.el
(autoload (quote gnus-article-prepare-display) "gnus-art" "\
;;;***
\f
;;;### (autoloads (gnus-user-format-function-D gnus-user-format-function-d)
-;;;;;; "gnus-diary" "gnus/gnus-diary.el" (18310 14585))
+;;;;;; "gnus-diary" "gnus/gnus-diary.el" (18448 4532))
;;; Generated autoloads from gnus/gnus-diary.el
(autoload (quote gnus-user-format-function-d) "gnus-diary" "\
;;;***
\f
;;;### (autoloads (gnus-registry-install-hooks gnus-registry-initialize)
-;;;;;; "gnus-registry" "gnus/gnus-registry.el" (18310 14586))
+;;;;;; "gnus-registry" "gnus/gnus-registry.el" (18490 24741))
;;; Generated autoloads from gnus/gnus-registry.el
(autoload (quote gnus-registry-initialize) "gnus-registry" "\
;;;***
\f
;;;### (autoloads (gdb-script-mode jdb pdb perldb xdb dbx sdb gud-gdb)
-;;;;;; "gud" "progmodes/gud.el" (18368 29740))
+;;;;;; "gud" "progmodes/gud.el" (18432 46544))
;;; Generated autoloads from progmodes/gud.el
(autoload (quote gud-gdb) "gud" "\
;;;### (autoloads (hi-lock-write-interactive-patterns hi-lock-unface-buffer
;;;;;; hi-lock-face-phrase-buffer hi-lock-face-buffer hi-lock-line-face-buffer
;;;;;; global-hi-lock-mode hi-lock-mode) "hi-lock" "hi-lock.el"
-;;;;;; (18310 14570))
+;;;;;; (18612 9509))
;;; Generated autoloads from hi-lock.el
(autoload (quote hi-lock-mode) "hi-lock" "\
Write active REGEXPs into buffer as comments (if possible). They may
be read the next time file is loaded or when the \\[hi-lock-find-patterns] command
is issued. The inserted regexps are in the form of font lock keywords.
- (See `font-lock-keywords'.) They may be edited and re-loaded with \\[hi-lock-find-patterns],
- any valid `font-lock-keywords' form is acceptable. When a file is
- loaded the patterns are read if `hi-lock-file-patterns-policy is
+ (See `font-lock-keywords'.) They may be edited and re-loaded with \\[hi-lock-find-patterns],
+ any valid `font-lock-keywords' form is acceptable. When a file is
+ loaded the patterns are read if `hi-lock-file-patterns-policy' is
'ask and the user responds y to the prompt, or if
`hi-lock-file-patterns-policy' is bound to a function and that
function returns t.
;;;***
\f
;;;### (autoloads (list-holidays holidays) "holidays" "calendar/holidays.el"
-;;;;;; (18310 14580))
+;;;;;; (18593 55294))
;;; Generated autoloads from calendar/holidays.el
(autoload (quote holidays) "holidays" "\
;;;***
\f
-;;;### (autoloads (icomplete-mode) "icomplete" "icomplete.el" (18326
-;;;;;; 18335))
+;;;### (autoloads (icomplete-mode) "icomplete" "icomplete.el" (18612
+;;;;;; 9509))
;;; Generated autoloads from icomplete.el
(defvar icomplete-mode nil "\
;;;***
\f
;;;### (autoloads (image-mode-maybe image-minor-mode image-mode)
-;;;;;; "image-mode" "image-mode.el" (18310 14571))
+;;;;;; "image-mode" "image-mode.el" (18615 34896))
;;; Generated autoloads from image-mode.el
(push '("\\.jpe?g\\'" . image-mode) auto-mode-alist)
(push '("\\.png\\'" . image-mode) auto-mode-alist)
\f
;;;### (autoloads (kmacro-end-call-mouse kmacro-end-and-call-macro
;;;;;; kmacro-end-or-call-macro kmacro-start-macro-or-insert-counter
-;;;;;; kmacro-call-macro kmacro-end-macro kmacro-start-macro) "kmacro"
-;;;;;; "kmacro.el" (18310 14572))
+;;;;;; kmacro-call-macro kmacro-end-macro kmacro-start-macro kmacro-exec-ring-item)
+;;;;;; "kmacro" "kmacro.el" (18584 56069))
;;; Generated autoloads from kmacro.el
(global-set-key "\C-x(" 'kmacro-start-macro)
(global-set-key "\C-x)" 'kmacro-end-macro)
(global-set-key "\C-x\C-k" 'kmacro-keymap)
(autoload 'kmacro-keymap "kmacro" "Keymap for keyboard macro commands." t 'keymap)
+(autoload (quote kmacro-exec-ring-item) "kmacro" "\
+Execute item ITEM from the macro ring.
+
+\(fn ITEM ARG)" nil nil)
+
(autoload (quote kmacro-start-macro) "kmacro" "\
Record subsequent keyboard input, defining a keyboard macro.
The commands are recorded even as they are executed.
\f
;;;### (autoloads (makefile-imake-mode makefile-bsdmake-mode makefile-makepp-mode
;;;;;; makefile-gmake-mode makefile-automake-mode makefile-mode)
-;;;;;; "make-mode" "progmodes/make-mode.el" (18310 14600))
+;;;;;; "make-mode" "progmodes/make-mode.el" (18432 19261))
;;; Generated autoloads from progmodes/make-mode.el
(autoload (quote makefile-mode) "make-mode" "\
;;;;;; message-signature-file message-signature message-indent-citation-function
;;;;;; message-cite-function message-yank-prefix message-citation-line-function
;;;;;; message-send-mail-function message-user-organization-file
-;;;;;; message-signature-separator message-from-style) "message"
-;;;;;; "gnus/message.el" (18408 28171))
+;;;;;; message-from-style) "message" "gnus/message.el" (18519 8938))
;;; Generated autoloads from gnus/message.el
(defvar message-from-style (quote default) "\
(custom-autoload (quote message-from-style) "message" t)
-(defvar message-signature-separator "^-- *$" "\
-Regexp matching the signature separator.")
-
-(custom-autoload (quote message-signature-separator) "message" t)
-
(defvar message-user-organization-file "/usr/lib/news/organization" "\
*Local news organization file.")
(custom-autoload (quote message-yank-prefix) "message" t)
-(defvar message-cite-function (quote message-cite-original) "\
+(defvar message-cite-function (quote message-cite-original-without-signature) "\
*Function for citing an original message.
Predefined functions include `message-cite-original' and
`message-cite-original-without-signature'.
;;;;;; uncomment-region comment-kill comment-set-column comment-indent
;;;;;; comment-indent-default comment-normalize-vars comment-multi-line
;;;;;; comment-padding comment-style comment-column) "newcomment"
-;;;;;; "newcomment.el" (18385 29912))
+;;;;;; "newcomment.el" (18421 31051))
;;; Generated autoloads from newcomment.el
(defalias (quote indent-for-comment) (quote comment-indent))
;;;***
\f
;;;### (autoloads (org-export-icalendar-combine-agenda-files org-export-icalendar-all-agenda-files
-;;;;;; org-export-icalendar-this-file org-diary org-tags-view org-todo-list
-;;;;;; org-agenda-list org-cycle-agenda-files org-batch-agenda org-agenda
+;;;;;; org-export-icalendar-this-file org-diary org-agenda-list-stuck-projects
+;;;;;; org-tags-view org-todo-list org-search-view org-agenda-list
+;;;;;; org-cycle-agenda-files org-batch-store-agenda-views org-store-agenda-views
+;;;;;; org-batch-agenda-csv org-batch-agenda org-agenda org-agenda-to-appt
;;;;;; org-remember-handler org-remember org-remember-apply-template
-;;;;;; org-remember-annotation org-store-link orgtbl-mode turn-on-orgtbl
-;;;;;; org-global-cycle org-cycle org-mode) "org" "textmodes/org.el"
-;;;;;; (18310 14605))
+;;;;;; org-remember-annotation org-remember-insinuate org-open-at-point-global
+;;;;;; org-insert-link-global org-store-link orgtbl-mode turn-on-orgtbl
+;;;;;; org-run-like-in-org-mode turn-on-orgstruct++ turn-on-orgstruct
+;;;;;; orgstruct-mode org-global-cycle org-cycle org-mode) "org"
+;;;;;; "textmodes/org.el" (18463 9021))
;;; Generated autoloads from textmodes/org.el
(autoload (quote org-mode) "org" "\
`indent-relative', like TAB normally does. See the option
`org-cycle-emulate-tab' for details.
-- Special case: if point is the beginning of the buffer and there is no
- headline in line 1, this function will act as if called with prefix arg.
+- Special case: if point is at the beginning of the buffer and there is
+ no headline in line 1, this function will act as if called with prefix arg.
+ But only if also the variable `org-cycle-global-at-bob' is t.
\(fn &optional ARG)" t nil)
\(fn &optional ARG)" t nil)
+(autoload (quote orgstruct-mode) "org" "\
+Toggle the minor more `orgstruct-mode'.
+This mode is for using Org-mode structure commands in other modes.
+The following key behave as if Org-mode was active, if the cursor
+is on a headline, or on a plain list item (both in the definition
+of Org-mode).
+
+M-up Move entry/item up
+M-down Move entry/item down
+M-left Promote
+M-right Demote
+M-S-up Move entry/item up
+M-S-down Move entry/item down
+M-S-left Promote subtree
+M-S-right Demote subtree
+M-q Fill paragraph and items like in Org-mode
+C-c ^ Sort entries
+C-c - Cycle list bullet
+TAB Cycle item visibility
+M-RET Insert new heading/item
+S-M-RET Insert new TODO heading / Chekbox item
+C-c C-c Set tags / toggle checkbox
+
+\(fn &optional ARG)" t nil)
+
+(autoload (quote turn-on-orgstruct) "org" "\
+Unconditionally turn on `orgstruct-mode'.
+
+\(fn)" nil nil)
+
+(autoload (quote turn-on-orgstruct++) "org" "\
+Unconditionally turn on `orgstruct-mode', and force org-mode indentations.
+In addition to setting orgstruct-mode, this also exports all indentation and
+autofilling variables from org-mode into the buffer. Note that turning
+off orgstruct-mode will *not* remove these additional settings.
+
+\(fn)" nil nil)
+
+(autoload (quote org-run-like-in-org-mode) "org" "\
+Not documented
+
+\(fn CMD)" nil nil)
+
(autoload (quote turn-on-orgtbl) "org" "\
Unconditionally turn on `orgtbl-mode'.
(autoload (quote org-store-link) "org" "\
\\<org-mode-map>Store an org-link to the current location.
-This link can later be inserted into an org-buffer with
-\\[org-insert-link].
+This link is added to `org-stored-links' and can later be inserted
+into an org-buffer with \\[org-insert-link].
+
For some link types, a prefix arg is interpreted:
For links to usenet articles, arg negates `org-usenet-links-prefer-google'.
For file links, arg negates `org-context-in-file-links'.
\(fn ARG)" t nil)
+(autoload (quote org-insert-link-global) "org" "\
+Insert a link like Org-mode does.
+This command can be called in any mode to insert a link in Org-mode syntax.
+
+\(fn)" t nil)
+
+(autoload (quote org-open-at-point-global) "org" "\
+Follow a link like Org-mode does.
+This command can be called in any mode to follow a link that has
+Org-mode syntax.
+
+\(fn)" t nil)
+
+(autoload (quote org-remember-insinuate) "org" "\
+Setup remember.el for use wiht Org-mode.
+
+\(fn)" nil nil)
+
(autoload (quote org-remember-annotation) "org" "\
Return a link to the current location as an annotation for remember.el.
If you are using Org-mode files as target for data storage with
(autoload (quote org-remember-apply-template) "org" "\
Initialize *remember* buffer with template, invoke `org-mode'.
This function should be placed into `remember-mode-hook' and in fact requires
-to be run from that hook to fucntion properly.
+to be run from that hook to function properly.
\(fn &optional USE-CHAR SKIP-INTERACTIVE)" nil nil)
If there is an active region, make sure remember uses it as initial content
of the remember buffer.
-\(fn)" t nil)
+When called interactively with a `C-u' prefix argument GOTO, don't remember
+anything, just go to the file/headline where the selected template usually
+stores its notes. With a double prefix arg `C-u C-u', go to the last
+note stored by remember.
+
+Lisp programs can set ORG-FORCE-REMEMBER-TEMPLATE-CHAR to a character
+associated with a template in `org-remember-templates'.
+
+\(fn &optional GOTO ORG-FORCE-REMEMBER-TEMPLATE-CHAR)" t nil)
(autoload (quote org-remember-handler) "org" "\
Store stuff from remember.el into an org file.
Key Cursor position Note gets inserted
-----------------------------------------------------------------------------
-RET buffer-start as level 2 heading at end of file
+RET buffer-start as level 1 heading at end of file
RET on headline as sublevel of the heading at cursor
RET no heading at cursor position, level taken from context.
Or use prefix arg to specify level manually.
So the fastest way to store the note is to press RET RET to append it to
the default file. This way your current train of thought is not
-interrupted, in accordance with the principles of remember.el. But with
-little extra effort, you can push it directly to the correct location.
+interrupted, in accordance with the principles of remember.el.
+You can also get the fast execution without prompting by using
+C-u C-c C-c to exit the remember buffer. See also the variable
+`org-remember-store-without-prompt'.
Before being stored away, the function ensures that the text has a
headline, i.e. a first line that starts with a \"*\". If not, a headline
\(fn)" nil nil)
+(autoload (quote org-agenda-to-appt) "org" "\
+Activate appointments found in `org-agenda-files'.
+With a \\[universal-argument] prefix, refresh the list of
+appointements.
+
+If FILTER is t, interactively prompt the user for a regular
+expression, and filter out entries that don't match it.
+
+If FILTER is a string, use this string as a regular expression
+for filtering entries out.
+
+FILTER can also be an alist with the car of each cell being
+either 'headline or 'category. For example:
+
+ '((headline \"IMPORTANT\")
+ (category \"Work\"))
+
+will only add headlines containing IMPORTANT or headlines
+belonging to the \"Work\" category.
+
+\(fn &optional REFRESH FILTER)" t nil)
+
(autoload (quote org-agenda) "org" "\
Dispatch agenda commands to collect entries to the agenda buffer.
-Prompts for a character to select a command. Any prefix arg will be passed
+Prompts for a command to execute. Any prefix arg will be passed
on to the selected command. The default selections are:
-g
+
a Call `org-agenda-list' to display the agenda for current day or week.
t Call `org-todo-list' to display the global todo list.
T Call `org-todo-list' to display the global todo list, select only
m Call `org-tags-view' to display headlines with tags matching
a condition (the user is prompted for the condition).
M Like `m', but select only TODO entries, no ordinary headlines.
-l Create a timeeline for the current buffer.
+L Create a timeline for the current buffer.
+e Export views to associated files.
More commands can be added by configuring the variable
`org-agenda-custom-commands'. In particular, specific tags and TODO keyword
searches can be pre-defined in this way.
If the current buffer is in Org-mode and visiting a file, you can also
-first press `1' to indicate that the agenda should be temporarily (until the
-next use of \\[org-agenda]) restricted to the current file.
+first press `<' once to indicate that the agenda should be temporarily
+\(until the next use of \\[org-agenda]) restricted to the current file.
+Pressing `<' twice means to restrict to the current subtree or region
+\(if active).
-\(fn ARG)" t nil)
+\(fn ARG &optional KEYS RESTRICTION)" t nil)
(autoload (quote org-batch-agenda) "org" "\
-Run an agenda command in batch mode, send result to STDOUT.
-CMD-KEY is a string that is also a key in `org-agenda-custom-commands'.
+Run an agenda command in batch mode and send the result to STDOUT.
+If CMD-KEY is a string of length 1, it is used as a key in
+`org-agenda-custom-commands' and triggers this command. If it is a
+longer string it is used as a tags/todo match string.
Paramters are alternating variable names and values that will be bound
before running the agenda command.
\(fn CMD-KEY &rest PARAMETERS)" nil (quote macro))
+(autoload (quote org-batch-agenda-csv) "org" "\
+Run an agenda command in batch mode and send the result to STDOUT.
+If CMD-KEY is a string of length 1, it is used as a key in
+`org-agenda-custom-commands' and triggers this command. If it is a
+longer string it is used as a tags/todo match string.
+Paramters are alternating variable names and values that will be bound
+before running the agenda command.
+
+The output gives a line for each selected agenda item. Each
+item is a list of comma-separated values, like this:
+
+category,head,type,todo,tags,date,time,extra,priority-l,priority-n
+
+category The category of the item
+head The headline, without TODO kwd, TAGS and PRIORITY
+type The type of the agenda entry, can be
+ todo selected in TODO match
+ tagsmatch selected in tags match
+ diary imported from diary
+ deadline a deadline on given date
+ scheduled scheduled on given date
+ timestamp entry has timestamp on given date
+ closed entry was closed on given date
+ upcoming-deadline warning about deadline
+ past-scheduled forwarded scheduled item
+ block entry has date block including g. date
+todo The todo keyword, if any
+tags All tags including inherited ones, separated by colons
+date The relevant date, like 2007-2-14
+time The time, like 15:00-16:50
+extra Sting with extra planning info
+priority-l The priority letter if any was given
+priority-n The computed numerical priority
+agenda-day The day in the agenda where this is listed
+
+\(fn CMD-KEY &rest PARAMETERS)" nil (quote macro))
+
+(autoload (quote org-store-agenda-views) "org" "\
+Not documented
+
+\(fn &rest PARAMETERS)" t nil)
+
+(autoload (quote org-batch-store-agenda-views) "org" "\
+Run all custom agenda commands that have a file argument.
+
+\(fn &rest PARAMETERS)" nil (quote macro))
+
(autoload (quote org-cycle-agenda-files) "org" "\
Cycle through the files in `org-agenda-files'.
If the current buffer visits an agenda file, find the next one in the list.
\(fn)" t nil)
(autoload (quote org-agenda-list) "org" "\
-Produce a weekly view from all files in variable `org-agenda-files'.
-The view will be for the current week, but from the overview buffer you
-will be able to go to other weeks.
-With one \\[universal-argument] prefix argument INCLUDE-ALL, all unfinished TODO items will
-also be shown, under the current date.
-With two \\[universal-argument] prefix argument INCLUDE-ALL, all TODO entries marked DONE
-on the days are also shown. See the variable `org-log-done' for how
-to turn on logging.
+Produce a daily/weekly view from all files in variable `org-agenda-files'.
+The view will be for the current day or week, but from the overview buffer
+you will be able to go to other days/weeks.
+
+With one \\[universal-argument] prefix argument INCLUDE-ALL,
+all unfinished TODO items will also be shown, before the agenda.
+This feature is considered obsolete, please use the TODO list or a block
+agenda instead.
+
+With a numeric prefix argument in an interactive call, the agenda will
+span INCLUDE-ALL days. Lisp programs should instead specify NDAYS to change
+the number of days. NDAYS defaults to `org-agenda-ndays'.
+
START-DAY defaults to TODAY, or to the most recent match for the weekday
given in `org-agenda-start-on-weekday'.
-NDAYS defaults to `org-agenda-ndays'.
\(fn &optional INCLUDE-ALL START-DAY NDAYS)" t nil)
+(autoload (quote org-search-view) "org" "\
+Show all entries that contain words or regular expressions.
+If the first character of the search string is an asterisks,
+search only the headlines.
+
+The search string is broken into \"words\" by splitting at whitespace.
+The individual words are then interpreted as a boolean expression with
+logical AND. Words prefixed with a minus must not occur in the entry.
+Words without a prefix or prefixed with a plus must occur in the entry.
+Matching is case-insensitive and the words are enclosed by word delimiters.
+
+Words enclosed by curly braces are interpreted as regular expressions
+that must or must not match in the entry.
+
+This command searches the agenda files, and in addition the files listed
+in `org-agenda-text-search-extra-files'.
+
+\(fn &optional ARG STRING)" t nil)
+
(autoload (quote org-todo-list) "org" "\
Show all TODO entries from all agenda file in a single list.
The prefix arg can be used to select a specific TODO keyword and limit
the list to these. When using \\[universal-argument], you will be prompted
for a keyword. A numeric prefix directly selects the Nth keyword in
-`org-todo-keywords'.
+`org-todo-keywords-1'.
\(fn ARG)" t nil)
\(fn &optional TODO-ONLY MATCH)" t nil)
+(autoload (quote org-agenda-list-stuck-projects) "org" "\
+Create agenda view for projects that are stuck.
+Stuck projects are project that have no next actions. For the definitions
+of what a project is and how to check if it stuck, customize the variable
+`org-stuck-projects'.
+MATCH is being ignored.
+
+\(fn &rest IGNORE)" t nil)
+
(autoload (quote org-diary) "org" "\
Return diary information from org-files.
This function can be used in a \"sexp\" diary entry in the Emacs calendar.
date range matching the selected date. Deadlines will
also be listed, on the expiration day.
+ :sexp List entries resulting from diary-like sexps.
+
:deadline List any deadlines past due, or due within
`org-deadline-warning-days'. The listing occurs only
in the diary for *today*, not at any other date. If
&%%(org-diary)
If you don't give any arguments (as in the example above), the default
-arguments (:deadline :scheduled :timestamp) are used. So the example above may
-also be written as
+arguments (:deadline :scheduled :timestamp :sexp) are used.
+So the example above may also be written as
- &%%(org-diary :deadline :timestamp :scheduled)
+ &%%(org-diary :deadline :timestamp :sexp :scheduled)
The function expects the lisp variables `entry' and `date' to be provided
by the caller, because this is how the calendar works. Don't use this
\(fn)" t nil)
+;;;***
+\f
+;;;### (autoloads (org-export-as-latex org-export-region-as-latex
+;;;;;; org-replace-region-by-latex org-export-as-latex-to-buffer
+;;;;;; org-export-as-latex-batch) "org-export-latex" "textmodes/org-export-latex.el"
+;;;;;; (18427 8817))
+;;; Generated autoloads from textmodes/org-export-latex.el
+
+(autoload (quote org-export-as-latex-batch) "org-export-latex" "\
+Call `org-export-as-latex', may be used in batch processing as
+emacs --batch
+ --load=$HOME/lib/emacs/org.el
+ --eval \"(setq org-export-headline-levels 2)\"
+ --visit=MyFile --funcall org-export-as-latex-batch
+
+\(fn)" nil nil)
+
+(autoload (quote org-export-as-latex-to-buffer) "org-export-latex" "\
+Call `org-exort-as-latex` with output to a temporary buffer.
+No file is created. The prefix ARG is passed through to `org-export-as-latex'.
+
+\(fn ARG)" t nil)
+
+(autoload (quote org-replace-region-by-latex) "org-export-latex" "\
+Replace the region from BEG to END with its LaTeX export.
+It assumes the region has `org-mode' syntax, and then convert it to
+LaTeX. This can be used in any buffer. For example, you could
+write an itemized list in `org-mode' syntax in an LaTeX buffer and
+then use this command to convert it.
+
+\(fn BEG END)" t nil)
+
+(autoload (quote org-export-region-as-latex) "org-export-latex" "\
+Convert region from BEG to END in `org-mode' buffer to LaTeX.
+If prefix arg BODY-ONLY is set, omit file header, footer, and table of
+contents, and only produce the region of converted text, useful for
+cut-and-paste operations.
+If BUFFER is a buffer or a string, use/create that buffer as a target
+of the converted LaTeX. If BUFFER is the symbol `string', return the
+produced LaTeX as a string and leave not buffer behind. For example,
+a Lisp program could call this function in the following way:
+
+ (setq latex (org-export-region-as-latex beg end t 'string))
+
+When called interactively, the output buffer is selected, and shown
+in a window. A non-interactive call will only retunr the buffer.
+
+\(fn BEG END &optional BODY-ONLY BUFFER)" t nil)
+
+(autoload (quote org-export-as-latex) "org-export-latex" "\
+Export current buffer to a LaTeX file.
+If there is an active region, export only the region. The prefix
+ARG specifies how many levels of the outline should become
+headlines. The default is 3. Lower levels will be exported
+depending on `org-export-latex-low-levels'. The default is to
+convert them as description lists. When HIDDEN is non-nil, don't
+display the LaTeX buffer. EXT-PLIST is a property list with
+external parameters overriding org-mode's default settings, but
+still inferior to file-local settings. When TO-BUFFER is
+non-nil, create a buffer with that name and export to that
+buffer. If TO-BUFFER is the symbol `string', don't leave any
+buffer behind but just return the resulting LaTeX as a string.
+When BODY-ONLY is set, don't produce the file header and footer,
+simply return the content of \begin{document}...\end{document},
+without even the \begin{document} and \end{document} commands.
+when PUB-DIR is set, use this as the publishing directory.
+
+\(fn ARG &optional HIDDEN EXT-PLIST TO-BUFFER BODY-ONLY PUB-DIR)" t nil)
+
+;;;***
+\f
+;;;### (autoloads (org-irc-store-link) "org-irc" "textmodes/org-irc.el"
+;;;;;; (18427 8818))
+;;; Generated autoloads from textmodes/org-irc.el
+
+(autoload (quote org-irc-store-link) "org-irc" "\
+Dispatch to the appropreate function to store a link to
+something IRC related
+
+\(fn)" nil nil)
+
+;;;***
+\f
+;;;### (autoloads (org-publish-current-project org-publish-current-file
+;;;;;; org-publish-all org-publish) "org-publish" "textmodes/org-publish.el"
+;;;;;; (18427 8818))
+;;; Generated autoloads from textmodes/org-publish.el
+
+(autoload (quote org-publish) "org-publish" "\
+Publish PROJECT.
+
+\(fn PROJECT &optional FORCE)" t nil)
+
+(autoload (quote org-publish-all) "org-publish" "\
+Publish all projects.
+With prefix argument, force publish all files.
+
+\(fn &optional FORCE)" t nil)
+
+(autoload (quote org-publish-current-file) "org-publish" "\
+Publish the current file.
+With prefix argument, force publish the file.
+
+\(fn &optional FORCE)" t nil)
+
+(autoload (quote org-publish-current-project) "org-publish" "\
+Publish the project associated with the current file.
+With a prefix argument, force publishing of all files in
+the project.
+
+\(fn &optional FORCE)" t nil)
+
;;;***
\f
;;;### (autoloads (outline-minor-mode outline-mode) "outline" "outline.el"
;;;***
\f
-;;;### (autoloads nil "paragraphs" "textmodes/paragraphs.el" (18310
-;;;;;; 14605))
+;;;### (autoloads nil "paragraphs" "textmodes/paragraphs.el" (18432
+;;;;;; 17907))
;;; Generated autoloads from textmodes/paragraphs.el
(put 'paragraph-start 'safe-local-variable 'stringp)
(put 'paragraph-separate 'safe-local-variable 'stringp)
;;;***
\f
;;;### (autoloads (pgg-gpg-symmetric-key-p) "pgg-gpg" "pgg-gpg.el"
-;;;;;; (18310 14576))
+;;;;;; (18580 44915))
;;; Generated autoloads from pgg-gpg.el
(autoload (quote pgg-gpg-symmetric-key-p) "pgg-gpg" "\
;;;;;; ps-spool-region ps-spool-buffer-with-faces ps-spool-buffer
;;;;;; ps-print-region-with-faces ps-print-region ps-print-buffer-with-faces
;;;;;; ps-print-buffer ps-print-customize ps-print-color-p ps-paper-type
-;;;;;; ps-page-dimensions-database) "ps-print" "ps-print.el" (18310
-;;;;;; 14577))
+;;;;;; ps-page-dimensions-database) "ps-print" "ps-print.el" (18419
+;;;;;; 51077))
;;; Generated autoloads from ps-print.el
(defvar ps-page-dimensions-database (list (list (quote a4) (/ (* 72 21.0) 2.54) (/ (* 72 29.7) 2.54) "A4") (list (quote a3) (/ (* 72 29.7) 2.54) (/ (* 72 42.0) 2.54) "A3") (list (quote letter) (* 72 8.5) (* 72 11.0) "Letter") (list (quote legal) (* 72 8.5) (* 72 14.0) "Legal") (list (quote letter-small) (* 72 7.68) (* 72 10.16) "LetterSmall") (list (quote tabloid) (* 72 11.0) (* 72 17.0) "Tabloid") (list (quote ledger) (* 72 17.0) (* 72 11.0) "Ledger") (list (quote statement) (* 72 5.5) (* 72 8.5) "Statement") (list (quote executive) (* 72 7.5) (* 72 10.0) "Executive") (list (quote a4small) (* 72 7.47) (* 72 10.85) "A4Small") (list (quote b4) (* 72 10.125) (* 72 14.33) "B4") (list (quote b5) (* 72 7.16) (* 72 10.125) "B5")) "\
;;;***
\f
;;;### (autoloads (jython-mode python-mode run-python) "python" "progmodes/python.el"
-;;;;;; (18326 18336))
+;;;;;; (18612 9510))
;;; Generated autoloads from progmodes/python.el
(add-to-list (quote interpreter-mode-alist) (quote ("jython" . jython-mode)))
;;;***
\f
;;;### (autoloads (shell shell-dumb-shell-regexp) "shell" "shell.el"
-;;;;;; (18376 17161))
+;;;;;; (18567 43470))
;;; Generated autoloads from shell.el
(defvar shell-dumb-shell-regexp "cmd\\(proxy\\)?\\.exe" "\
;;;***
\f
-;;;### (autoloads nil "simple" "simple.el" (18389 59148))
+;;;### (autoloads nil "simple" "simple.el" (18593 55294))
;;; Generated autoloads from simple.el
(put 'fill-prefix 'safe-local-variable 'string-or-null-p)
;;;***
\f
;;;### (autoloads (smerge-mode smerge-ediff) "smerge-mode" "smerge-mode.el"
-;;;;;; (18310 14577))
+;;;;;; (18469 40408))
;;; Generated autoloads from smerge-mode.el
(autoload (quote smerge-ediff) "smerge-mode" "\
;;;***
\f
-;;;### (autoloads (solitaire) "solitaire" "play/solitaire.el" (18310
-;;;;;; 14597))
+;;;### (autoloads (solitaire) "solitaire" "play/solitaire.el" (18612
+;;;;;; 9510))
;;; Generated autoloads from play/solitaire.el
(autoload (quote solitaire) "solitaire" "\
Undo moves using \\[solitaire-undo].
Check for possible moves using \\[solitaire-do-check].
\(The variable `solitaire-auto-eval' controls whether to automatically
-check after each move or undo)
+check after each move or undo.)
What is Solitaire?
;;;***
\f
;;;### (autoloads (speedbar-get-focus speedbar-frame-mode) "speedbar"
-;;;;;; "speedbar.el" (18310 14577))
+;;;;;; "speedbar.el" (18612 9509))
;;; Generated autoloads from speedbar.el
(defalias (quote speedbar) (quote speedbar-frame-mode))
;;;***
\f
-;;;### (autoloads (locate-library) "subr" "subr.el" (18388 4644))
+;;;### (autoloads (locate-library) "subr" "subr.el" (18621 22670))
;;; Generated autoloads from subr.el
(autoload (quote locate-library) "subr" "\
If the optional third arg PATH is specified, that list of directories
is used instead of `load-path'.
-When called from a program, the file name is normaly returned as a
+When called from a program, the file name is normally returned as a
string. When run interactively, the argument INTERACTIVE-CALL is t,
and the file name is displayed in the echo area.
;;;***
\f
-;;;### (autoloads (tar-mode) "tar-mode" "tar-mode.el" (18310 14577))
+;;;### (autoloads (tar-mode) "tar-mode" "tar-mode.el" (18490 63050))
;;; Generated autoloads from tar-mode.el
(autoload (quote tar-mode) "tar-mode" "\
;;;;;; tex-start-commands tex-start-options slitex-run-command latex-run-command
;;;;;; tex-run-command tex-offer-save tex-main-file tex-first-line-header-regexp
;;;;;; tex-directory tex-shell-file-name) "tex-mode" "textmodes/tex-mode.el"
-;;;;;; (18310 14607))
+;;;;;; (18570 7790))
;;; Generated autoloads from textmodes/tex-mode.el
(defvar tex-shell-file-name nil "\
\f
;;;### (autoloads (tool-bar-local-item-from-menu tool-bar-add-item-from-menu
;;;;;; tool-bar-local-item tool-bar-add-item) "tool-bar" "tool-bar.el"
-;;;;;; (18310 14578))
+;;;;;; (18612 9509))
;;; Generated autoloads from tool-bar.el
(put (quote tool-bar-mode) (quote standard-value) (quote (t)))
Info node `(elisp)Tool Bar'. Items are added from left to right.
ICON is the base name of a file containing the image to use. The
-function will first try to use low-color/ICON.xpm if display-color-cells
+function will first try to use low-color/ICON.xpm if `display-color-cells'
is less or equal to 256, then ICON.xpm, then ICON.pbm, and finally
ICON.xbm, using `find-image'.
;;;***
\f
;;;### (autoloads (tpu-edt-on tpu-edt-mode) "tpu-edt" "emulation/tpu-edt.el"
-;;;;;; (18310 14582))
+;;;;;; (18612 9509))
;;; Generated autoloads from emulation/tpu-edt.el
(defvar tpu-edt-mode nil "\
;;;### (autoloads (tramp-unload-tramp tramp-completion-handle-file-name-completion
;;;;;; tramp-completion-handle-file-name-all-completions tramp-unload-file-name-handlers
;;;;;; tramp-file-name-handler tramp-completion-file-name-regexp
-;;;;;; tramp-file-name-regexp) "tramp" "net/tramp.el" (18355 36599))
+;;;;;; tramp-file-name-regexp) "tramp" "net/tramp.el" (18574 8385))
;;; Generated autoloads from net/tramp.el
(defvar tramp-unified-filenames (not (featurep (quote xemacs))) "\
;;;***
\f
;;;### (autoloads (url-register-auth-scheme url-get-authentication)
-;;;;;; "url-auth" "url/url-auth.el" (18377 44624))
+;;;;;; "url-auth" "url/url-auth.el" (18417 24432))
;;; Generated autoloads from url/url-auth.el
(autoload (quote url-get-authentication) "url-auth" "\
;;;***
\f
;;;### (autoloads (url-http-options url-http-file-attributes url-http-file-exists-p
-;;;;;; url-http) "url-http" "url/url-http.el" (18310 14608))
+;;;;;; url-http) "url-http" "url/url-http.el" (18621 22671))
;;; Generated autoloads from url/url-http.el
(autoload (quote url-http) "url-http" "\
(defconst url-https-asynchronous-p t "\
HTTPS retrievals are asynchronous.")
+ (autoload 'url-default-expander "url-expand")
-(defalias (quote url-https-expand-file-name) (quote url-http-expand-file-name))
+(defalias (quote url-https-expand-file-name) (quote url-default-expander))
(autoload 'url-https "url-http")
(autoload 'url-https-file-exists-p "url-http")
(autoload 'url-https-file-readable-p "url-http")
;;;;;; vc-directory vc-merge vc-insert-headers vc-version-other-window
;;;;;; vc-diff vc-register vc-next-action vc-do-command edit-vc-file
;;;;;; with-vc-file vc-branch-part vc-trunk-p vc-before-checkin-hook
-;;;;;; vc-checkin-hook vc-checkout-hook) "vc" "vc.el" (18342 38263))
+;;;;;; vc-checkin-hook vc-checkout-hook) "vc" "vc.el" (18414 39572))
;;; Generated autoloads from vc.el
(defvar vc-checkout-hook nil "\
;;;***
\f
-;;;### (autoloads nil "vc-hg" "vc-hg.el" (18310 14578))
+;;;### (autoloads nil "vc-hg" "vc-hg.el" (18479 55600))
;;; Generated autoloads from vc-hg.el
(defun vc-hg-registered (file)
"Return non-nil if FILE is registered with hg."
;;;***
\f
;;;### (autoloads (woman-find-file woman-dired-find-file woman) "woman"
-;;;;;; "woman.el" (18316 51172))
+;;;;;; "woman.el" (18430 52623))
;;; Generated autoloads from woman.el
(autoload (quote woman) "woman" "\
;;;;;; "register.el" "replace.el" "rfn-eshadow.el" "s-region.el"
;;;;;; "saveplace.el" "sb-image.el" "scroll-bar.el" "select.el"
;;;;;; "soundex.el" "startup.el" "subdirs.el" "tempo.el" "textmodes/bib-mode.el"
-;;;;;; "textmodes/makeinfo.el" "textmodes/page-ext.el" "textmodes/page.el"
-;;;;;; "textmodes/refbib.el" "textmodes/refer.el" "textmodes/reftex-auc.el"
-;;;;;; "textmodes/reftex-dcr.el" "textmodes/reftex-ref.el" "textmodes/reftex-sel.el"
-;;;;;; "textmodes/reftex-toc.el" "textmodes/texnfo-upd.el" "textmodes/text-mode.el"
-;;;;;; "timezone.el" "tooltip.el" "tree-widget.el" "uniquify.el"
-;;;;;; "url/url-about.el" "url/url-cookie.el" "url/url-dired.el"
-;;;;;; "url/url-expand.el" "url/url-ftp.el" "url/url-history.el"
-;;;;;; "url/url-imap.el" "url/url-methods.el" "url/url-nfs.el" "url/url-proxy.el"
-;;;;;; "url/url-vars.el" "url/vc-dav.el" "vc-hooks.el" "vcursor.el"
-;;;;;; "version.el" "vms-patch.el" "vmsproc.el" "vt-control.el"
-;;;;;; "vt100-led.el" "w32-fns.el" "w32-vars.el" "widget.el" "window.el"
-;;;;;; "x-dnd.el") (18410 21129 646372))
+;;;;;; "textmodes/makeinfo.el" "textmodes/org-mac-message.el" "textmodes/org-mouse.el"
+;;;;;; "textmodes/page-ext.el" "textmodes/page.el" "textmodes/refbib.el"
+;;;;;; "textmodes/refer.el" "textmodes/reftex-auc.el" "textmodes/reftex-dcr.el"
+;;;;;; "textmodes/reftex-ref.el" "textmodes/reftex-sel.el" "textmodes/reftex-toc.el"
+;;;;;; "textmodes/texnfo-upd.el" "textmodes/text-mode.el" "timezone.el"
+;;;;;; "tooltip.el" "tree-widget.el" "uniquify.el" "url/url-about.el"
+;;;;;; "url/url-cookie.el" "url/url-dired.el" "url/url-expand.el"
+;;;;;; "url/url-ftp.el" "url/url-history.el" "url/url-imap.el" "url/url-methods.el"
+;;;;;; "url/url-nfs.el" "url/url-proxy.el" "url/url-vars.el" "url/vc-dav.el"
+;;;;;; "vc-hooks.el" "vcursor.el" "version.el" "vms-patch.el" "vmsproc.el"
+;;;;;; "vt-control.el" "vt100-led.el" "w32-fns.el" "w32-vars.el"
+;;;;;; "widget.el" "window.el" "x-dnd.el") (18625 23607 152932))
;;;***
\f
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
2008-02-06 Richard Stallman <rms@gnu.org>
* mh-seq.el (mh-make-seq, mh-seq-name): Use defsubst.
;;;;;; mh-do-at-event-location mh-in-show-buffer with-mh-folder-updating
;;;;;; mh-defstruct mh-mark-active-p mh-make-local-hook defmacro-mh
;;;;;; defun-mh mh-funcall-if-exists mh-do-in-xemacs mh-do-in-gnu-emacs
-;;;;;; mh-require-cl) "mh-acros" "mh-acros.el" (18368 9296))
+;;;;;; mh-require-cl) "mh-acros" "mh-acros.el" (18345 62202))
;;; Generated autoloads from mh-acros.el
(autoload (quote mh-require-cl) "mh-acros" "\
;;;### (autoloads (mh-alias-grab-from-field mh-alias-for-from-p mh-alias-address-to-alias
;;;;;; mh-alias-letter-expand-alias mh-alias-minibuffer-confirm-address
;;;;;; mh-read-address mh-alias-reload-maybe) "mh-alias" "mh-alias.el"
-;;;;;; (18310 3180))
+;;;;;; (18305 34284))
;;; Generated autoloads from mh-alias.el
(autoload (quote mh-alias-reload-maybe) "mh-alias" "\
\f
;;;### (autoloads (mh-insert-auto-fields mh-show-buffer-message-number
;;;;;; mh-send mh-reply mh-redistribute mh-forward mh-extract-rejected-mail
-;;;;;; mh-edit-again) "mh-comp" "mh-comp.el" (18310 3180))
+;;;;;; mh-edit-again) "mh-comp" "mh-comp.el" (18305 34284))
;;; Generated autoloads from mh-comp.el
(autoload (quote mh-edit-again) "mh-comp" "\
;;;;;; mh-prev-button mh-page-msg mh-next-unread-msg mh-next-undeleted-msg
;;;;;; mh-next-button mh-modify mh-last-msg mh-inc-folder mh-goto-msg
;;;;;; mh-first-msg mh-execute-commands mh-delete-msg-no-motion
-;;;;;; mh-delete-msg) "mh-folder" "mh-folder.el" (18310 3180))
+;;;;;; mh-delete-msg) "mh-folder" "mh-folder.el" (18305 34283))
;;; Generated autoloads from mh-folder.el
(autoload (quote mh-delete-msg) "mh-folder" "\
;;;### (autoloads (mh-undo-folder mh-store-msg mh-sort-folder mh-pipe-msg
;;;;;; mh-page-digest-backwards mh-page-digest mh-pack-folder mh-list-folders
;;;;;; mh-kill-folder mh-copy-msg mh-burst-digest) "mh-funcs" "mh-funcs.el"
-;;;;;; (18310 3180))
+;;;;;; (18305 34283))
;;; Generated autoloads from mh-funcs.el
(autoload (quote mh-burst-digest) "mh-funcs" "\
;;;;;; mh-identity-insert-attribution-verb mh-identity-handler-attribution-verb
;;;;;; mh-identity-handler-signature mh-identity-handler-gpg-identity
;;;;;; mh-insert-identity mh-identity-add-menu mh-identity-make-menu)
-;;;;;; "mh-identity" "mh-identity.el" (18310 3180))
+;;;;;; "mh-identity" "mh-identity.el" (18305 34282))
;;; Generated autoloads from mh-identity.el
(autoload (quote mh-identity-make-menu) "mh-identity" "\
;;;***
\f
-;;;### (autoloads (mh-inc-spool-make) "mh-inc" "mh-inc.el" (18310
-;;;;;; 3180))
+;;;### (autoloads (mh-inc-spool-make) "mh-inc" "mh-inc.el" (18305
+;;;;;; 34282))
;;; Generated autoloads from mh-inc.el
(autoload (quote mh-inc-spool-make) "mh-inc" "\
;;;### (autoloads (mh-spamprobe-whitelist mh-spamprobe-blacklist
;;;;;; mh-bogofilter-whitelist mh-bogofilter-blacklist mh-spamassassin-identify-spammers
;;;;;; mh-spamassassin-whitelist mh-spamassassin-blacklist mh-junk-whitelist
-;;;;;; mh-junk-blacklist) "mh-junk" "mh-junk.el" (18310 3180))
+;;;;;; mh-junk-blacklist) "mh-junk" "mh-junk.el" (18305 34282))
;;; Generated autoloads from mh-junk.el
(autoload (quote mh-junk-blacklist) "mh-junk" "\
;;;### (autoloads (mh-letter-toggle-header-field-display-button mh-complete-word
;;;;;; mh-position-on-field mh-letter-next-header-field mh-yank-cur-msg
;;;;;; mh-insert-signature mh-letter-mode) "mh-letter" "mh-letter.el"
-;;;;;; (18310 3180))
+;;;;;; (18305 34282))
;;; Generated autoloads from mh-letter.el
(autoload (quote mh-letter-mode) "mh-letter" "\
\f
;;;### (autoloads (mh-narrow-to-to mh-narrow-to-subject mh-narrow-to-range
;;;;;; mh-narrow-to-from mh-narrow-to-cc mh-delete-subject-or-thread
-;;;;;; mh-delete-subject) "mh-limit" "mh-limit.el" (18310 3180))
+;;;;;; mh-delete-subject) "mh-limit" "mh-limit.el" (18305 34282))
;;; Generated autoloads from mh-limit.el
(autoload (quote mh-delete-subject) "mh-limit" "\
;;;;;; mh-toggle-mime-buttons mh-toggle-mh-decode-mime-flag mh-mime-save-parts
;;;;;; mh-folder-toggle-mime-part mh-folder-save-mime-part mh-folder-inline-mime-part
;;;;;; mh-display-with-external-viewer mh-buffer-data) "mh-mime"
-;;;;;; "mh-mime.el" (18310 3180))
+;;;;;; "mh-mime.el" (18305 34282))
;;; Generated autoloads from mh-mime.el
(autoload (quote mh-buffer-data) "mh-mime" "\
\f
;;;### (autoloads (mh-print-msg mh-ps-print-toggle-color mh-ps-print-toggle-faces
;;;;;; mh-ps-print-msg-file mh-ps-print-msg) "mh-print" "mh-print.el"
-;;;;;; (18310 3180))
+;;;;;; (18305 34282))
;;; Generated autoloads from mh-print.el
(autoload (quote mh-ps-print-msg) "mh-print" "\
\f
;;;### (autoloads (mh-msg-num-width-to-column mh-msg-num-width mh-scan-format
;;;;;; mh-set-cmd-note mh-scan-msg-search-regexp mh-scan-msg-number-regexp)
-;;;;;; "mh-scan" "mh-scan.el" (18310 3180))
+;;;;;; "mh-scan" "mh-scan.el" (18305 34281))
;;; Generated autoloads from mh-scan.el
(autoload (quote mh-scan-msg-number-regexp) "mh-scan" "\
;;;;;; mh-index-group-by-folder mh-index-visit-folder mh-index-previous-folder
;;;;;; mh-index-next-folder mh-index-sequenced-messages mh-index-ticked-messages
;;;;;; mh-index-new-messages mh-search) "mh-search" "mh-search.el"
-;;;;;; (18310 3180))
+;;;;;; (18305 34281))
;;; Generated autoloads from mh-search.el
(autoload (quote mh-search) "mh-search" "\
;;;;;; mh-read-seq-default mh-widen mh-toggle-tick mh-put-msg-in-seq
;;;;;; mh-narrow-to-tick mh-narrow-to-seq mh-msg-is-in-seq mh-list-sequences
;;;;;; mh-delete-seq mh-delete-msg-from-seq mh-catchup) "mh-seq"
-;;;;;; "mh-seq.el" (18368 9296))
+;;;;;; "mh-seq.el" (18345 62269))
;;; Generated autoloads from mh-seq.el
(autoload (quote mh-catchup) "mh-seq" "\
;;;;;; mh-show-mode mh-show-font-lock-keywords-with-cite mh-show-font-lock-keywords
;;;;;; mh-invalidate-show-buffer mh-clean-msg-header mh-display-msg
;;;;;; mh-start-of-uncleaned-message mh-showing-mode mh-maybe-show
-;;;;;; mh-header-display mh-show) "mh-show" "mh-show.el" (18310
-;;;;;; 3180))
+;;;;;; mh-header-display mh-show) "mh-show" "mh-show.el" (18305
+;;;;;; 34281))
;;; Generated autoloads from mh-show.el
(autoload (quote mh-show) "mh-show" "\
;;;***
\f
;;;### (autoloads (mh-speed-add-folder mh-speed-invalidate-map mh-speed-flists
-;;;;;; mh-folder-speedbar-buttons) "mh-speed" "mh-speed.el" (18310
-;;;;;; 3180))
+;;;;;; mh-folder-speedbar-buttons) "mh-speed" "mh-speed.el" (18305
+;;;;;; 34281))
;;; Generated autoloads from mh-speed.el
(autoload (quote mh-folder-speedbar-buttons) "mh-speed" "\
;;;;;; mh-thread-print-scan-lines mh-thread-generate mh-thread-parse-scan-line
;;;;;; mh-thread-inc mh-toggle-threads mh-thread-refile mh-thread-previous-sibling
;;;;;; mh-thread-next-sibling mh-thread-delete mh-thread-ancestor)
-;;;;;; "mh-thread" "mh-thread.el" (18310 3180))
+;;;;;; "mh-thread" "mh-thread.el" (18305 34281))
;;; Generated autoloads from mh-thread.el
(autoload (quote mh-thread-ancestor) "mh-thread" "\
;;;;;; mh-help mh-set-help mh-ephem-message mh-find-path mh-logo-display
;;;;;; mh-replace-string mh-quote-pick-expr mh-mapc mh-make-local-vars
;;;;;; mh-delete-line mh-colors-in-use-p mh-colors-available-p mh-beginning-of-word
-;;;;;; mh-search-from-end) "mh-utils" "mh-utils.el" (18310 3180))
+;;;;;; mh-search-from-end) "mh-utils" "mh-utils.el" (18305 34280))
;;; Generated autoloads from mh-utils.el
(autoload (quote mh-search-from-end) "mh-utils" "\
;;;***
\f
;;;### (autoloads (mh-set-x-image-cache-directory mh-show-xface)
-;;;;;; "mh-xface" "mh-xface.el" (18368 9296))
+;;;;;; "mh-xface" "mh-xface.el" (18344 28424))
;;; Generated autoloads from mh-xface.el
(autoload (quote mh-show-xface) "mh-xface" "\
;;;***
\f
;;;### (autoloads nil nil ("mh-buffers.el" "mh-compat.el" "mh-e.el"
-;;;;;; "mh-gnus.el" "mh-tool-bar.el") (18410 20740 617101))
+;;;;;; "mh-gnus.el" "mh-tool-bar.el") (18625 23307 35037))
;;;***
\f
(end-of-line)
(point))))
(forward-line 1)
- (while (looking-at "^\\(\\w*\\)\\(;\\w*\\)?[=:\t ]+\\(<[\t ]*file://\\)\\(.*\\)$")
+ (while (looking-at "^\\([A-Za-z][-A-Za-z0-9]*\
+\\|[0-9]+\\(?:\\.[0-9]+\\)*\\)\\(;[-A-Za-z0-9]+\\)*[=:\t ]+\
+\\(<[\t ]*file://\\)\\(.*\\)$")
(setq name (match-string 1)
value (match-string 4))
;; Need to handle file:///D:/... as generated by OpenLDAP
;; unless this spits out a complete line, including the '\n' at the
;; end.
;; The device number is returned as "-1", because there will be a virtual
-;; device number set in `tramp-handle-file-attributes'
+;; device number set in `tramp-handle-file-attributes'.
(defconst tramp-perl-file-attributes "\
@stat = lstat($ARGV[0]);
if (($stat[2] & 0170000) == 0120000)
$uid = ($ARGV[1] eq \"integer\") ? $stat[4] : \"\\\"\" . getpwuid($stat[4]) . \"\\\"\";
$gid = ($ARGV[1] eq \"integer\") ? $stat[5] : \"\\\"\" . getgrgid($stat[5]) . \"\\\"\";
printf(
- \"(\\\"%s\\\" %s %u %s %s (%u %u) (%u %u) (%u %u) %u %u t (%u . %u) (%u %u))\\n\",
+ \"(\\\"%s\\\" %s %u %s %s (%u %u) (%u %u) (%u %u) %u %u t (%u . %u) (%u . %u))\\n\",
$filename,
$type,
$stat[3],
;; provided by "lstat" aren't unique, because we operate on different hosts.
;; So we use virtual device numbers, generated by Tramp. Both Ange-FTP and
;; EFS use device number "-1". In order to be different, we use device number
-;; (-1 x), whereby "x" is unique for a given (multi-method method user host).
+;; (-1 . x), whereby "x" is unique for a given (multi-method method user host).
(defvar tramp-devices nil
"Keeps virtual device numbers.")
;; File Editing.
+;; `make-temp-file' exists in Emacs only. The third parameter SUFFIX
+;; has been introduced with Emacs 22. We try it, if it fails, we fall
+;; back to `make-temp-name', creating the temporary file immediately
+;; in order to avoid a security hole.
(defsubst tramp-make-temp-file (filename)
- (concat
- (funcall (if (fboundp 'make-temp-file) 'make-temp-file 'make-temp-name)
- (expand-file-name tramp-temp-name-prefix
- (tramp-temporary-file-directory)))
- (file-name-extension filename t)))
+ "Create a temporary file (compat function).
+Add the extension of FILENAME, if existing."
+ (let* (file-name-handler-alist
+ (prefix (expand-file-name
+ (symbol-value 'tramp-temp-name-prefix)
+ (tramp-temporary-file-directory)))
+ (extension (file-name-extension filename t))
+ result)
+ (condition-case nil
+ (setq result
+ (funcall (symbol-function 'make-temp-file) prefix nil extension))
+ (error
+ ;; We use our own implementation, taken from files.el.
+ (while
+ (condition-case ()
+ (progn
+ (setq result (concat (make-temp-name prefix) extension))
+ (write-region
+ "" nil result nil 'silent nil
+ ;; 7th parameter is MUSTBENEW in Emacs, and
+ ;; CODING-SYSTEM in XEmacs. It is not a security
+ ;; hole in XEmacs if we cannot use this parameter,
+ ;; because XEmacs uses a user-specific subdirectory
+ ;; with 0700 permissions.
+ (when (not (featurep 'xemacs)) 'excl))
+ nil)
+ (file-already-exists t))
+ ;; The file was somehow created by someone else between
+ ;; `make-temp-name' and `write-region', let's try again.
+ nil)))
+ result))
(defun tramp-handle-file-local-copy (filename)
"Like `file-local-copy' for tramp files."
(t (tramp-make-tramp-file-name
multi-method method user host "")))))))
+(defun tramp-find-file-name-coding-system-alist (filename tmpname)
+ "Like `find-operation-coding-system' for Tramp filenames.
+Tramp's `insert-file-contents' and `write-region' work over
+temporary file names. If `file-coding-system-alist' contains an
+expression, which matches more than the file name suffix, the
+coding system might not be determined. This function repairs it."
+ (let (result)
+ (dolist (elt file-coding-system-alist result)
+ (when (and (consp elt) (string-match (car elt) filename))
+ ;; We found a matching entry in `file-coding-system-alist'.
+ ;; So we add a similar entry, but with the temporary file name
+ ;; as regexp.
+ (add-to-list
+ 'result (cons (regexp-quote tmpname) (cdr elt)) 'append)))))
+
(defun tramp-handle-insert-file-contents
(filename &optional visit beg end replace)
"Like `insert-file-contents' for tramp files."
(tramp-message-for-buffer
multi-method method user host
9 "Inserting local temp file `%s'..." local-copy)
- (setq result (insert-file-contents local-copy nil beg end replace))
- (when visit
- (setq buffer-file-name filename)
- (set-visited-file-modtime)
- (set-buffer-modified-p nil))
- ;; Now `last-coding-system-used' has right value. Remember it.
- (when (boundp 'last-coding-system-used)
- (setq coding-system-used (symbol-value 'last-coding-system-used)))
+ ;; We must ensure that `file-coding-system-alist' matches
+ ;; `local-copy'.
+ (let ((file-coding-system-alist
+ (tramp-find-file-name-coding-system-alist filename local-copy)))
+ (setq result (insert-file-contents local-copy nil beg end replace))
+ (when visit
+ (setq buffer-file-name filename)
+ (set-visited-file-modtime)
+ (set-buffer-modified-p nil))
+ ;; Now `last-coding-system-used' has right value. Remember it.
+ (when (boundp 'last-coding-system-used)
+ (setq coding-system-used (symbol-value 'last-coding-system-used))))
(tramp-message-for-buffer
multi-method method user host
9 "Inserting local temp file `%s'...done" local-copy)
;; Set current buffer. If connection wasn't open, `file-modes' has
;; changed it accidently.
(set-buffer curbuf)
- ;; We say `no-message' here because we don't want the visited file
- ;; modtime data to be clobbered from the temp file. We call
- ;; `set-visited-file-modtime' ourselves later on.
- (tramp-run-real-handler
- 'write-region
- (if confirm ; don't pass this arg unless defined for backward compat.
- (list start end tmpfil append 'no-message lockname confirm)
- (list start end tmpfil append 'no-message lockname)))
- ;; Now, `last-coding-system-used' has the right value. Remember it.
- (when (boundp 'last-coding-system-used)
- (setq coding-system-used (symbol-value 'last-coding-system-used)))
+ ;; We say `no-message' here because we don't want the visited
+ ;; file modtime data to be clobbered from the temp file. We
+ ;; call `set-visited-file-modtime' ourselves later on. We must
+ ;; ensure that `file-coding-system-alist' matches `tmpfil'.
+ (let ((file-coding-system-alist
+ (tramp-find-file-name-coding-system-alist filename tmpfil)))
+ (tramp-run-real-handler
+ 'write-region
+ (if confirm ; don't pass this arg unless defined for backward compat.
+ (list start end tmpfil append 'no-message lockname confirm)
+ (list start end tmpfil append 'no-message lockname)))
+ ;; Now, `last-coding-system-used' has the right value. Remember it.
+ (when (boundp 'last-coding-system-used)
+ (setq coding-system-used (symbol-value 'last-coding-system-used))))
;; The permissions of the temporary file should be set. If
;; filename does not exist (eq modes nil) it has been renamed to
;; the backup file. This case `save-buffer' handles
;; (setq edebug-trace t)
;; (edebug-trace "%s" (with-output-to-string (backtrace)))
(save-match-data
- (let* ((filename (apply 'tramp-file-name-for-operation operation args))
+ (let* ((filename
+ (tramp-run-real-handler
+ 'substitute-in-file-name
+ (list (apply 'tramp-file-name-for-operation operation args))))
(completion (tramp-completion-mode-p filename))
(foreign (tramp-find-foreign-file-name-handler filename)))
(with-parsed-tramp-file-name filename nil
(unless (assoc string tramp-devices)
(add-to-list 'tramp-devices
(list string (length tramp-devices))))
- (list -1 (nth 1 (assoc string tramp-devices)))))
+ (cons -1 (nth 1 (assoc string tramp-devices)))))
(defun tramp-file-mode-from-int (mode)
"Turn an integer representing a file mode into an ls(1)-like string."
;; are auto-frobbed from configure.ac, so you should edit that file and run
;; "autoconf && ./configure" to change them.
-(defconst tramp-version "2.0.57"
+(defconst tramp-version "2.0.58-pre"
"This version of Tramp.")
(defconst tramp-bug-report-address "tramp-devel@gnu.org"
;; comment-end = ""
(progn (backward-char) (skip-syntax-backward " "))
(cond
- ((save-restriction
- (narrow-to-region (line-beginning-position) (point))
- (goto-char (point-min))
- (re-search-forward (concat comment-end-skip "\\'") nil t))
+ ((save-excursion
+ (save-restriction
+ (narrow-to-region (line-beginning-position) (point))
+ (goto-char (point-min))
+ (re-search-forward (concat comment-end-skip "\\'") nil t)))
(goto-char (match-beginning 0)))
;; comment-end-skip not found. Maybe we're at EOB which implicitly
;; closes the comment.
(integer :tag "size")))))
:group 'fast-lock)
-(defcustom fast-lock-cache-directories '("." "~/.emacs-flc")
+(defcustom fast-lock-cache-directories '("~/.emacs-flc")
; - `internal', keep each file's Font Lock cache file in the same file.
; - `external', keep each file's Font Lock cache file in the same directory.
"*Directories in which Font Lock cache files are saved and read.
((\"^/your/true/home/directory/\" . \".\") \"~/.emacs-flc\")
would cause a file's current directory to be used if the file is under your
-home directory hierarchy, or otherwise the absolute directory `~/.emacs-flc'."
+home directory hierarchy, or otherwise the absolute directory `~/.emacs-flc'.
+For security reasons, it is not advisable to use the file's current directory
+to avoid the possibility of using the cache of another user."
:type '(repeat (radio (directory :tag "directory")
(cons :tag "Matching"
(regexp :tag "regexp")
(directory :tag "directory"))))
:group 'fast-lock)
+(put 'fast-lock-cache-directories 'risky-local-variable t)
(defcustom fast-lock-save-events '(kill-buffer kill-emacs)
"*Events under which caches will be saved.
(process-send-eof process)
(while (eq 'run (process-status process))
(accept-process-output process 5))
+ ;; Accept any remaining pending output coming after the
+ ;; status change.
+ (accept-process-output process 5)
(setq status (process-status process)
exit-status (process-exit-status process))
(delete-process process)
;;; Code:
(defgroup solitaire nil
- "Game of solitaire."
+ "Game of Solitaire."
:prefix "solitaire-"
:group 'games)
(defvar solitaire-mode-map nil
- "Keymap for playing solitaire.")
+ "Keymap for playing Solitaire.")
(defcustom solitaire-mode-hook nil
- "Hook to run upon entry to solitaire."
+ "Hook to run upon entry to Solitaire."
:type 'hook
:group 'solitaire)
(put 'solitaire-mode 'mode-class 'special)
(defun solitaire-mode ()
- "Major mode for playing solitaire.
-To learn how to play solitaire, see the documentation for function
+ "Major mode for playing Solitaire.
+To learn how to play Solitaire, see the documentation for function
`solitaire'.
\\<solitaire-mode-map>
The usual mnemonic keys move the cursor around the board; in addition,
Undo moves using \\[solitaire-undo].
Check for possible moves using \\[solitaire-do-check].
\(The variable `solitaire-auto-eval' controls whether to automatically
-check after each move or undo)
+check after each move or undo.)
What is Solitaire?
;; And here's the spoiler:)
(defun solitaire-solve ()
- "Spoil solitaire by solving the game for you - nearly ...
+ "Spoil Solitaire by solving the game for you - nearly ...
... stops with five stones left ;)"
(interactive)
+ (when (< solitaire-stones 32)
+ (error "Cannot solve game in progress"))
(let ((allmoves [up up S-down up left left S-right up up left S-down
up up right right S-left down down down S-up up
S-down down down down S-up left left down
;; This file contains (most of) the adaptations to cc-mode required for the
;; integration of AWK Mode.
-;; It is organised thusly, the sections being separated by page breaks:
+;; It is organized thusly, the sections being separated by page breaks:
;; 1. The AWK Mode syntax table.
-;; 2. Regular expressions for analysing AWK code.
+;; 2. Regular expressions for analyzing AWK code.
;; 3. Indentation calculation stuff ("c-awk-NL-prop text-property").
;; 4. Syntax-table property/font-locking stuff, including the
;; font-lock-keywords setting.
;;
;; ANCHOR-STATE-/DIV identifies whether a / at ANCHOR would have been a
;; division sign (value t) or a regexp opener (value nil). The idea is that
- ;; we analyse the line from ANCHOR up till point to determine what the / at
+ ;; we analyze the line from ANCHOR up till point to determine what the / at
;; point is.
;;
;; The result is what ANCHOR-STATE-/DIV (see above) is where point is left.
(c-keep-region-active)
(= arg 0)))
+(defun c-defun-name ()
+ "Return the name of the current defun, or NIL if there isn't one.
+\"Defun\" here means a function, or other top level construct
+with a brace block."
+ (interactive)
+ (c-save-buffer-state
+ (beginning-of-defun-function end-of-defun-function
+ where pos name-end)
+
+ (save-excursion
+ ;; Move back out of any macro/comment/string we happen to be in.
+ (c-beginning-of-macro)
+ (setq pos (c-literal-limits))
+ (if pos (goto-char (car pos)))
+
+ (setq where (c-where-wrt-brace-construct))
+
+ ;; Move to the beginning of the current defun, if any, if we're not
+ ;; already there.
+ (if (eq where 'outwith-function)
+ nil
+ (unless (eq where 'at-header)
+ (c-backward-to-nth-BOF-{ 1 where)
+ (c-beginning-of-decl-1))
+
+ ;; Pick out the defun name, according to the type of defun.
+ (cond
+ ((and (looking-at c-type-prefix-key)
+ (progn (c-forward-token-2 2) ; over "struct foo "
+ (eq (char-after) ?\{)))
+ ;; struct, union, enum, or similar:
+ (c-backward-syntactic-ws)
+ (setq name-end (point))
+ (buffer-substring-no-properties
+ (progn
+ (c-backward-token-2 2)
+ (point))
+ name-end))
+
+ ((looking-at "DEFUN\\_>")
+ ;; DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory, ...) ==> Ffile_name_directory
+ ;; DEFUN(POSIX::STREAM-LOCK, stream lockp &key BLOCK SHARED START LENGTH) ==> POSIX::STREAM-LOCK
+ (down-list 1)
+ (c-forward-syntactic-ws)
+ (when (eq (char-after) ?\")
+ (forward-sexp 1)
+ (c-forward-token-2)) ; over the comma and following WS.
+ (buffer-substring-no-properties
+ (point)
+ (progn
+ (c-forward-token-2)
+ (c-backward-syntactic-ws)
+ (point))))
+
+ (t
+ ;; Normal function or initializer.
+ (when (c-syntactic-re-search-forward "[{(]" nil t)
+ (backward-char)
+ (c-backward-syntactic-ws)
+ (when (eq (char-before) ?\=) ; struct foo bar = {0, 0} ;
+ (c-backward-token-2)
+ (c-backward-syntactic-ws))
+ (setq name-end (point))
+ (c-backward-token-2)
+ (buffer-substring-no-properties (point) name-end))))))))
+
(defun c-declaration-limits (near)
;; Return a cons of the beginning and end positions of the current
;; top level declaration or macro. If point is not inside any then
(goto-char (car decl-limits))
(push-mark (cdr decl-limits) nil t))))
+(defun c-cpp-define-name ()
+ "Return the name of the current CPP macro, or NIL if we're not in one."
+ (interactive)
+ (save-excursion
+ (and c-opt-cpp-macro-define-start
+ (c-beginning-of-macro)
+ (looking-at c-opt-cpp-macro-define-start)
+ (match-string-no-properties 1))))
+
\f
;; Movement by statements.
(defun c-in-comment-line-prefix-p ()
\f
;;; Variables also used at compile time.
-(defconst c-version "5.31.5"
+(defconst c-version "5.31.6"
"CC Mode version number.")
(defconst c-version-sym (intern c-version))
;; the searchable range.
(let* ((macro-start (c-query-macro-start))
(lim (max (or lim (point-min)) (or macro-start (point-min))))
- before-lparen after-rparen)
+ before-lparen after-rparen
+ (pp-count-out 20)) ; Max number of paren/brace constructs before we give up
(narrow-to-region lim (c-point 'eol))
;; Search backwards for the defun's argument list. We give up if we
;; {
(catch 'knr
- (while t ; go round one paren/bracket construct each time round.
+ (while (> pp-count-out 0) ; go back one paren/bracket pair each time.
+ (setq pp-count-out (1- pp-count-out))
(c-syntactic-skip-backward "^)]}")
(cond ((eq (char-before) ?\))
(setq after-rparen (point)))
(c-add-syntax 'inher-cont (c-point 'boi)))
;; CASE 5D.5: Continuation of the "expression part" of a
- ;; top level construct.
+ ;; top level construct. Or, perhaps, an unrecognised construct.
(t
- (while (and (eq (car (c-beginning-of-decl-1 containing-sexp))
+ (while (and (setq placeholder (point))
+ (eq (car (c-beginning-of-decl-1 containing-sexp))
'same)
(save-excursion
(c-backward-syntactic-ws)
- (eq (char-before) ?}))))
+ (eq (char-before) ?}))
+ (< (point) placeholder)))
(c-add-stmt-syntax
- (if (eq char-before-ip ?,)
+ (cond
+ ((eq (point) placeholder) 'statement) ; unrecognised construct
;; A preceding comma at the top level means that a
;; new variable declaration starts here. Use
;; topmost-intro-cont for it, for consistency with
;; the first variable declaration. C.f. case 5N.
- 'topmost-intro-cont
- 'statement-cont)
+ ((eq char-before-ip ?,) 'topmost-intro-cont)
+ (t 'statement-cont))
nil nil containing-sexp paren-state))
))
0 ,c-doc-markup-face-name prepend nil)
(,(concat header "\\(" "@" symbol "\\):")
1 ,c-doc-markup-face-name prepend nil)
- (,(concat "[#%]" symbol)
+ (,(concat "[#%@]" symbol)
0 ,c-doc-markup-face-name prepend nil))
))
will have been saved; the return value is ignored.
The function may extend the region to be fontified by setting the
-buffer local variables c-old-BEG and c-old-END.
+buffer local variables c-new-BEG and c-new-END.
The function is called even when font locking is disabled.
"define"))
(c-lang-defconst c-opt-cpp-macro-define-start
- ;; Regexp matching everything up to the macro body of a cpp define,
- ;; or the end of the logical line if there is none. Set if
- ;; c-opt-cpp-macro-define is.
+ ;; Regexp matching everything up to the macro body of a cpp define, or the
+ ;; end of the logical line if there is none. Submatch 1 is the name of the
+ ;; macro. Set if c-opt-cpp-macro-define is.
t (if (c-lang-const c-opt-cpp-macro-define)
(concat (c-lang-const c-opt-cpp-prefix)
(c-lang-const c-opt-cpp-macro-define)
- "[ \t]+\\(\\sw\\|_\\)+\\(\([^\)]*\)\\)?"
+ "[ \t]+\\(\\(\\sw\\|_\\)+\\)\\(\([^\)]*\)\\)?"
+ ;; ^ ^ #defined name
"\\([ \t]\\|\\\\\n\\)*")))
(c-lang-defvar c-opt-cpp-macro-define-start
(c-lang-const c-opt-cpp-macro-define-start))
(make-local-hook 'before-change-functions)
(add-hook 'before-change-functions 'c-before-change nil t)
(make-local-hook 'after-change-functions)
- (add-hook 'after-change-functions 'c-after-change nil t))
+ (add-hook 'after-change-functions 'c-after-change nil t)
+ (set (make-local-variable 'font-lock-extend-after-change-region-function)
+ 'c-extend-after-change-region)) ; Currently (2008-04), only used by AWK.
(defun c-setup-doc-comment-style ()
"Initialize the variables that depend on the value of `c-doc-comment-style'."
(when c-buffer-is-cc-mode
(if (or c-file-style c-file-offsets)
(c-make-styles-buffer-local t))
- (and c-file-style
- (c-set-style c-file-style))
+ (when c-file-style
+ (or (stringp c-file-style)
+ (error "c-file-style is not a string"))
+ (c-set-style c-file-style))
+
(and c-file-offsets
(mapcar
(lambda (langentry)
(setq c-old-EOM (point)))
(defun c-neutralize-CPP-line (beg end)
- ;; BEG and END bound a preprocessor line. Put a "punctuation" syntax-table
- ;; property on syntactically obtrusive characters, ones which would interact
- ;; syntactically with stuff outside the CPP line.
+ ;; BEG and END bound a region, typically a preprocessor line. Put a
+ ;; "punctuation" syntax-table property on syntactically obtrusive
+ ;; characters, ones which would interact syntactically with stuff outside
+ ;; this region.
;;
;; These are unmatched string delimiters, or unmatched
;; parens/brackets/braces. An unclosed comment is regarded as valid, NOT
;; obtrusive.
- (let (s)
- (while
- (progn
- (setq s (parse-partial-sexp beg end -1))
- (cond
- ((< (nth 0 s) 0) ; found an unmated ),},]
- (c-put-char-property (1- (point)) 'syntax-table '(1))
- t)
- ((nth 3 s) ; In a string
- (c-put-char-property (nth 8 s) 'syntax-table '(1))
- t)
- ((> (nth 0 s) 0) ; In a (,{,[
- (c-put-char-property (nth 1 s) 'syntax-table '(1))
- t)
- (t nil))))))
+ (save-excursion
+ (let (s)
+ (while
+ (progn
+ (setq s (parse-partial-sexp beg end -1))
+ (cond
+ ((< (nth 0 s) 0) ; found an unmated ),},]
+ (c-put-char-property (1- (point)) 'syntax-table '(1))
+ t)
+ ((nth 3 s) ; In a string
+ (c-put-char-property (nth 8 s) 'syntax-table '(1))
+ t)
+ ((> (nth 0 s) 0) ; In a (,{,[
+ (c-put-char-property (nth 1 s) 'syntax-table '(1))
+ t)
+ (t nil)))))))
(defun c-neutralize-syntax-in-CPP (begg endd old-len)
;; "Neutralize" every preprocessor line wholly or partially in the changed
;;
;; This function is the C/C++/ObjC value of `c-before-font-lock-function'.
;;
- ;; This function might do invisible changes.
+ ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!!
+ ;;
+ ;; This function might make hidden buffer changes.
(c-save-buffer-state (limits mbeg+1 beg end)
- ;; First calculate the region, possibly to be extended.
- (setq beg (min begg c-old-BOM))
+ ;; First determine the region, (beg end), which may need "neutralizing".
+ ;; This may not start inside a string, comment, or macro.
+ (goto-char c-old-BOM) ; already set to old start of macro or begg.
+ (setq beg
+ (if (setq limits (c-literal-limits))
+ (cdr limits) ; go forward out of any string or comment.
+ (point)))
+
(goto-char endd)
- (when (c-beginning-of-macro)
- (c-end-of-macro))
+ (if (setq limits (c-literal-limits))
+ (goto-char (car limits))) ; go backward out of any string or comment.
+ (if (c-beginning-of-macro)
+ (c-end-of-macro))
(setq end (max (+ (- c-old-EOM old-len) (- endd begg))
(point)))
+
;; Clear all old punctuation properties
(c-clear-char-property-with-value beg end 'syntax-table '(1))
(goto-char beg)
- (while (and (< (point) end)
- (search-forward-regexp c-anchored-cpp-prefix end t))
- ;; If we've found a "#" inside a string/comment, ignore it.
- (if (setq limits (c-literal-limits))
- (goto-char (cdr limits))
- (setq mbeg+1 (point))
- (c-end-of-macro) ; Do we need to go forward 1 char here? No!
- (c-neutralize-CPP-line mbeg+1 (point))))))
+ (let ((pps-position beg) pps-state)
+ (while (and (< (point) end)
+ (search-forward-regexp c-anchored-cpp-prefix end t))
+ ;; If we've found a "#" inside a string/comment, ignore it.
+ (setq pps-state
+ (parse-partial-sexp pps-position (point) nil nil pps-state)
+ pps-position (point))
+ (unless (or (nth 3 pps-state) ; in a string?
+ (nth 4 pps-state)) ; in a comment?
+ (setq mbeg+1 (point))
+ (c-end-of-macro) ; Do we need to go forward 1 char here? No!
+ (c-neutralize-CPP-line mbeg+1 (point))
+ (setq pps-position (point))))))) ; no need to update pps-state.
(defun c-before-change (beg end)
;; Function to be put on `before-change-function'. Primarily, this calls
(make-local-hook 'font-lock-mode-hook)
(add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t))
-(defmacro c-advise-fl-for-region (function)
- `(defadvice ,function (before get-awk-region activate)
-;; When font-locking an AWK Mode buffer, make sure that any string/regexp is
-;; completely font-locked.
- (when (eq major-mode 'awk-mode)
- (save-excursion
- (ad-set-arg 1 c-new-END) ; end
- (ad-set-arg 0 c-new-BEG))))) ; beg
-
-(c-advise-fl-for-region font-lock-after-change-function)
-(c-advise-fl-for-region jit-lock-after-change)
-(c-advise-fl-for-region lazy-lock-defer-rest-after-change)
-(c-advise-fl-for-region lazy-lock-defer-line-after-change)
+(defun c-extend-after-change-region (beg end old-len)
+ "Extend the region to be fontified, if necessary."
+ ;; Note: the parameters are ignored here. This somewhat indirect
+ ;; implementation exists because it is minimally different from the
+ ;; stand-alone CC Mode which, lacking
+ ;; font-lock-extend-after-change-region-function, is forced to use advice
+ ;; instead.
+ ;;
+ ;; Of the seven CC Mode languages, currently (2008-04) only AWK Mode makes
+ ;; non-null use of this function.
+ (cons c-new-BEG c-new-END))
\f
;; Support for C
("ellemtel"
(c-basic-offset . 3)
(c-comment-only-line-offset . 0)
- (c-hanging-braces-alist . ((substatement-open before after)))
+ (c-hanging-braces-alist . ((substatement-open before after)
+ (arglist-cont-nonempty)))
(c-offsets-alist . ((topmost-intro . 0)
(substatement . +)
(substatement-open . 0)
(case-label . +)
(access-label . -)
- (inclass . ++)
- (inline-open . 0)
- (arglist-cont-nonempty))))
-
+ (inclass . +)
+ (inline-open . 0))))
("linux"
(c-basic-offset . 8)
(c-comment-only-line-offset . 0)
matching-beg
;; Note this includes the case of an un-named main program,
;; in which case we go to (point-min).
- (message "No beginning found.")
+ (if (interactive-p) (message "No beginning found."))
nil)))
(defun f90-end-of-subprogram ()
;;; (forward-line 1)
(if (zerop count)
matching-end
- (message "No end found.")
+ (if (interactive-p) (message "No end found."))
nil)))
has-flymake-overlays))
(defface flymake-errline
- ;;+ '((((class color)) (:foreground "OrangeRed" :bold t :underline t))
- ;;+ '((((class color)) (:underline "OrangeRed"))
- '((((class color)) (:background "LightPink"))
+ '((((class color) (background dark)) (:background "Firebrick4"))
+ (((class color) (background light)) (:background "LightPink"))
(t (:bold t)))
"Face used for marking error lines."
:group 'flymake)
(defface flymake-warnline
- '((((class color)) (:background "LightBlue2"))
+ '((((class color) (background dark)) (:background "DarkBlue"))
+ (((class color) (background light)) (:background "LightBlue2"))
(t (:bold t)))
"Face used for marking warning lines."
:group 'flymake)
;; Builtin operators.
(concat "\\." (regexp-opt
'("and" "or" "not" "lt" "le" "eq" "ge"
- "gt" "ne" "true" "false")
+ "gt" "ne" "eqv" "neqv" "true" "false")
'paren) "\\.")
;; do/goto keywords and targets, and goto tags.
'("\\<\\(do\\|go *to\\)\\>[ \t]*\\([0-9]+\\)?"
(fortran-check-end-prog-re)))
(forward-line)
(beginning-of-line 2)
- (catch 'ok
- (while (re-search-forward fortran-end-prog-re nil 'move)
- (if (fortran-check-end-prog-re)
- (throw 'ok t))))
- (goto-char (match-beginning 0))
- (forward-line)))))
+ (when (catch 'ok
+ (while (re-search-forward fortran-end-prog-re nil 'move)
+ (if (fortran-check-end-prog-re)
+ (throw 'ok t))))
+ (goto-char (match-beginning 0))
+ (forward-line))))))
(defun fortran-previous-statement ()
"Move point to beginning of the previous Fortran statement.
(defconst gdb-source-file-regexp "\\(.+?\\), \\|\\([^, \n].*$\\)")
+(defun gdb-init-buffer ()
+ (set (make-local-variable 'gud-minor-mode)
+ (buffer-local-value 'gud-minor-mode gud-comint-buffer))
+ (set (make-local-variable 'tool-bar-map) gud-tool-bar-map)
+ (when gud-tooltip-mode
+ (make-local-variable 'gdb-define-alist)
+ (gdb-create-define-alist)
+ (add-hook 'after-save-hook 'gdb-create-define-alist nil t)))
+
(defun gdb-set-gud-minor-mode-existing-buffers ()
"Create list of source files for current GDB session."
(goto-char (point-min))
(when (and buffer-file-name
(member (file-name-nondirectory buffer-file-name)
gdb-source-file-list))
- (set (make-local-variable 'gud-minor-mode) 'gdba)
- (set (make-local-variable 'tool-bar-map) gud-tool-bar-map)
- (when gud-tooltip-mode
- (make-local-variable 'gdb-define-alist)
- (gdb-create-define-alist)
- (add-hook 'after-save-hook 'gdb-create-define-alist nil t))))))
+ (gdb-init-buffer)))))
(gdb-force-mode-line-update
(propertize "ready" 'face font-lock-variable-name-face)))
(setq gdb-flush-pending-output t)
(setq gud-running nil)
(gdb-force-mode-line-update
- (propertize "stopped"'face font-lock-warning-face))
+ (propertize "stopped" 'face font-lock-warning-face))
(setq gdb-output-sink 'user)
(setq gdb-input-queue nil)
(setq gdb-pending-triggers nil)
(with-current-buffer (gdb-get-buffer 'gdb-breakpoints-buffer)
(save-excursion
(let ((buffer-read-only nil))
- (goto-char (point-min))
- (while (< (point) (- (point-max) 1))
- (forward-line 1)
- (if (looking-at gdb-breakpoint-regexp)
- (progn
- (setq bptno (or (match-string 1) (match-string 2)))
- (setq flag (char-after (match-beginning 3)))
- (if (match-string 1)
- (setq gdb-parent-bptno-enabled (eq flag ?y)))
- (add-text-properties
- (match-beginning 3) (match-end 3)
- (if (eq flag ?y)
- '(face font-lock-warning-face)
- '(face font-lock-type-face)))
- (let ((bl (point))
- (el (line-end-position)))
- (if (re-search-forward " in \\(.*\\) at\\s-+" el t)
- (progn
- (add-text-properties
- (match-beginning 1) (match-end 1)
- '(face font-lock-function-name-face))
- (looking-at "\\(\\S-+\\):\\([0-9]+\\)")
+ (goto-char (point-min))
+ (while (< (point) (- (point-max) 1))
+ (forward-line 1)
+ (if (looking-at gdb-breakpoint-regexp)
+ (progn
+ (setq bptno (or (match-string 1) (match-string 2)))
+ (setq flag (char-after (match-beginning 3)))
+ (if (match-string 1)
+ (setq gdb-parent-bptno-enabled (eq flag ?y)))
+ (add-text-properties
+ (match-beginning 3) (match-end 3)
+ (if (eq flag ?y)
+ '(face font-lock-warning-face)
+ '(face font-lock-type-face)))
+ (let ((bl (point))
+ (el (line-end-position)))
+ (when (re-search-forward " in \\(.*\\) at" el t)
+ (add-text-properties
+ (match-beginning 1) (match-end 1)
+ '(face font-lock-function-name-face)))
+ (if (re-search-forward
+ ".*\\s-+\\(\\S-+\\):\\([0-9]+\\)$" nil t)
(let ((line (match-string 2))
(file (match-string 1)))
(add-text-properties bl el
- '(mouse-face highlight
- help-echo "mouse-2, RET: visit breakpoint"))
+ '(mouse-face highlight
+ help-echo "mouse-2, RET: visit breakpoint"))
(unless (file-exists-p file)
(setq file (cdr (assoc bptno gdb-location-alist))))
(if (and file
(not (string-equal file "File not found")))
(with-current-buffer
(find-file-noselect file 'nowarn)
- (set (make-local-variable 'gud-minor-mode)
- 'gdba)
- (set (make-local-variable 'tool-bar-map)
- gud-tool-bar-map)
+ (gdb-init-buffer)
;; Only want one breakpoint icon at each
;; location.
(save-excursion
(gdb-enqueue-input
(list (concat gdb-server-prefix "info source\n")
`(lambda () (gdb-get-location
- ,bptno ,line ,flag)))))))
- (if (re-search-forward
- "<\\(\\(\\sw\\|[_.]\\)+\\)\\(\\+[0-9]+\\)?>"
- el t)
+ ,bptno ,line ,flag))))))
+ (if (re-search-forward
+ "<\\(\\(\\sw\\|[_.]\\)+\\)\\(\\+[0-9]+\\)?>"
+ el t)
+ (add-text-properties
+ (match-beginning 1) (match-end 1)
+ '(face font-lock-function-name-face))
+ (end-of-line)
+ (re-search-backward "\\s-\\(\\S-*\\)"
+ bl t)
(add-text-properties
(match-beginning 1) (match-end 1)
- '(face font-lock-function-name-face))
- (end-of-line)
- (re-search-backward "\\s-\\(\\S-*\\)"
- bl t)
- (add-text-properties
- (match-beginning 1) (match-end 1)
- '(face font-lock-variable-name-face)))))))
- (end-of-line))))))
+ '(face font-lock-variable-name-face)))))))
+ (end-of-line))))))
(if (gdb-get-buffer 'gdb-assembler-buffer) (gdb-assembler-custom)))
(defun gdb-mouse-set-clear-breakpoint (event)
(interactive "e")
(mouse-minibuffer-check event)
(let ((posn (event-end event)))
- (if (buffer-file-name)
+ (if (or (buffer-file-name) (eq major-mode 'gdb-assembler-mode))
(if (numberp (posn-point posn))
(with-selected-window (posn-window posn)
(save-excursion
(if event (posn-set-point (event-end event)))
(save-excursion
(beginning-of-line 1)
- (if (looking-at "\\([0-9]+\\.?[0-9]*\\) .+ in .+ at\\s-+\\(\\S-+\\):\\([0-9]+\\)")
+ (if (looking-at "\\([0-9]+\\.?[0-9]*\\) .*\\s-+\\(\\S-+\\):\\([0-9]+\\)$")
(let ((bptno (match-string 1))
(file (match-string 2))
(line (match-string 3)))
(error "No location specified."))))
\f
-;; Frames buffer. This displays a perpetually correct bactracktrace
+;; Frames buffer. This displays a perpetually correct backtrace
;; (from the command `where').
;;
;; Alas, if your stack is deep, it is costly.
(remove-hook 'after-save-hook 'gdb-create-define-alist t))
(defun gdb-source-info ()
- "Find the source file where the program starts and displays it with related
+ "Find the source file where the program starts and display it with related
buffers."
(goto-char (point-min))
(if (and (search-forward "Located in " nil t)
(throw 'file-not-found nil))
(with-current-buffer
(find-file-noselect (match-string 0))
- (save-current-buffer
- (set (make-local-variable 'gud-minor-mode) 'gdba)
- (set (make-local-variable 'tool-bar-map) gud-tool-bar-map))
+ (gdb-init-buffer)
;; only want one breakpoint icon at each location
(save-excursion
(goto-line (string-to-number line))
buffer-file-name)
gdb-source-file-list)
(with-current-buffer (find-buffer-visiting buffer-file-name)
- (set (make-local-variable 'gud-minor-mode)
- (buffer-local-value 'gud-minor-mode gud-comint-buffer))
- (set (make-local-variable 'tool-bar-map) gud-tool-bar-map)))))
+ (gdb-init-buffer)))))
;;from put-image
(defun gdb-put-string (putstring pos &optional dprop &rest sprops)
(with-current-buffer buffer
(save-excursion
(goto-char (point-min))
- (if (search-forward address nil t)
+ (if (re-search-forward (concat "^0x0*" address) nil t)
(gdb-put-breakpoint-icon (eq flag ?y) bptno)))))))
(if (not (equal gdb-pc-address "main"))
(with-current-buffer buffer
(dolist (buffer (buffer-list))
(with-current-buffer buffer
(when (member buffer-file-name gdb-source-file-list)
- (set (make-local-variable 'gud-minor-mode)
- (buffer-local-value 'gud-minor-mode gud-comint-buffer))
- (set (make-local-variable 'tool-bar-map) gud-tool-bar-map)
- (when gud-tooltip-mode
- (make-local-variable 'gdb-define-alist)
- (gdb-create-define-alist)
- (add-hook 'after-save-hook 'gdb-create-define-alist nil t)))))
+ (gdb-init-buffer))))
(gdb-force-mode-line-update
(propertize "ready" 'face font-lock-variable-name-face)))
(if (and (eq gud-minor-mode 'gdba)
(not gdb-active-process))
(progn
- (with-current-buffer
- (window-buffer (let ((mouse (mouse-position)))
- (window-at (cadr mouse)
- (cddr mouse))))
+ (with-current-buffer (tooltip-event-buffer event)
(let ((define-elt (assoc expr gdb-define-alist)))
(unless (null define-elt)
(tooltip-show
(save-excursion
(beginning-of-line)
(cond
- ((looking-at "^#+\\s-*")
+ ((looking-at "^[ \t]*#+\\s-*")
;; Found a comment. Return nil to let normal filling take place.
nil)
(error nil))))))))
(defun python-comment-line-p ()
- "Return non-nil iff current line has only a comment."
+ "Return non-nil if and only if current line has only a comment."
(save-excursion
(end-of-line)
(when (eq 'comment (syntax-ppss-context (syntax-ppss)))
(looking-at (rx (or (syntax comment-start) line-end))))))
(defun python-blank-line-p ()
- "Return non-nil iff current line is blank."
+ "Return non-nil if and only if current line is blank."
(save-excursion
(beginning-of-line)
(looking-at "\\s-*$")))
"Skip out of any nested brackets.
Skip forward if FORWARD is non-nil, else backward.
If SYNTAX is non-nil it is the state returned by `syntax-ppss' at point.
-Return non-nil iff skipping was done."
+Return non-nil if and only if skipping was done."
(let ((depth (syntax-ppss-depth (or syntax (syntax-ppss))))
(forward (if forward -1 1)))
(unless (zerop depth)
;; invoked. Would support multiple processes better.
(when (or new (not (comint-check-proc python-buffer)))
(with-current-buffer
- (let* ((cmdlist (append (python-args-to-list cmd) '("-i")))
+ (let* ((cmdlist
+ (append (python-args-to-list cmd)
+ '("-i" "-c" "import sys; sys.path.remove('')")))
(path (getenv "PYTHONPATH"))
(process-environment ; to import emacs.py
(cons (concat "PYTHONPATH=" data-directory
(current-column))))
(^ '(- (1+ (current-indentation))))))
(add-hook 'pre-abbrev-expand-hook 'python-pea-hook nil t)
- (if (featurep 'hippie-exp)
- (set (make-local-variable 'hippie-expand-try-functions-list)
- (cons 'python-try-complete hippie-expand-try-functions-list)))
+ ;; Let's not mess with hippie-expand. Symbol-completion should rather be
+ ;; bound to another key, since it has different performance requirements.
+ ;; (if (featurep 'hippie-exp)
+ ;; (set (make-local-variable 'hippie-expand-try-functions-list)
+ ;; (cons 'python-try-complete hippie-expand-try-functions-list)))
;; Python defines TABs as being 8-char wide.
(set (make-local-variable 'tab-width) 8)
(when python-guess-indent (python-guess-indent))
((ps-e-overlay-get overlay 'face))
(t face)
))))
- (setq overlays (cdr overlays))))
+ (setq overlays (cdr overlays)))
+ ;; Ediff refinement overlays specify faces by name, as a
+ ;; string, not as symbols.
+ (if (stringp face)
+ (setq face (intern face))))
;; Plot up to this record.
(and before-string
(ps-plot-string before-string))
shell-dynamic-complete-environment-variable
shell-dynamic-complete-command
shell-replace-by-expanded-directory
+ shell-dynamic-complete-filename
comint-dynamic-complete-filename)
"List of functions called to perform completion.
This variable is used to initialize `comint-dynamic-complete-functions' in the
(insert " "))
success)))
+(defun shell-dynamic-complete-filename ()
+ "Dynamically complete the filename at point.
+This completes only if point is at a suitable position for a
+filename argument."
+ (interactive)
+ (let ((opoint (point))
+ (beg (comint-line-beginning-position)))
+ (when (save-excursion
+ (goto-char (if (re-search-backward "[;|&]" beg t)
+ (match-end 0)
+ beg))
+ (re-search-forward "[^ \t][ \t]" opoint t))
+ (comint-dynamic-complete-as-filename))))
(defun shell-match-partial-variable ()
"Return the shell variable at point, or nil if none is found."
;; we know here that next-error-function is a valid symbol we can funcall
(with-current-buffer next-error-last-buffer
(funcall next-error-function (prefix-numeric-value arg) reset)
- (run-hooks 'next-error-hook))))
+ (run-hooks 'next-error-hook)))
+ ;; This is a workaround for a redisplay bug (bug#197). The proper
+ ;; fix is in the trunk: see the 2008-07-28 change to xdisp.c by cyd.
+ (redisplay))
(defun next-error-internal ()
"Visit the source code corresponding to the `next-error' message at point."
"Toggle whether to fold or truncate long lines for the current buffer.
With prefix argument ARG, truncate long lines if ARG is positive,
otherwise don't truncate them. Note that in side-by-side
-windows, truncation is always enabled."
+windows, this command has no effect if `truncate-partial-width-windows'
+is non-nil."
(interactive "P")
(setq truncate-lines
(if (null arg)
(defcustom smerge-command-prefix "\C-c^"
"Prefix for `smerge-mode' commands."
:group 'smerge
- :type '(choice (string "\e") (string "\C-c^") (string "") string))
+ :type '(choice (const :tag "ESC" "\e")
+ (const :tag "C-c ^" "\C-c^" )
+ (const :tag "none" "")
+ string))
(easy-mmode-defmap smerge-mode-map
`((,smerge-command-prefix . ,smerge-basic-map))
where NAME is the name of the major display mode these functions are
for, and the remaining elements FUNCTION are functions to call in order.
Each function must return nil if interrupted, or t if completed.
-Stealthy functions which have a single operation should always return
-t. Functions which take a long time should maintain a state (where
-they are in their speedbar related calculations) and permit
-interruption. See `speedbar-check-vc' as a good example.")
+Stealthy functions which have a single operation should always return t.
+Functions which take a long time should maintain a state (where they
+are in their speedbar related calculations) and permit interruption.
+See `speedbar-check-vc' as a good example.")
(defvar speedbar-mode-functions-list
'(("files" (speedbar-item-info . speedbar-files-item-info)
;;; EVENTUALLY REMOVE THESE
-;; When I moved to a repeating timer, I had the horrible missfortune
-;; of loosing the ability for adaptive speed choice. This update
+;; When I moved to a repeating timer, I had the horrible misfortune
+;; of losing the ability for adaptive speed choice. This update
;; speed currently causes long delays when it should have been turned off.
(defvar speedbar-update-speed dframe-update-speed
"*Obsoleted variable. Use `dframe-update-speed'.")
(sexp :tag "Value"))))
(defcustom speedbar-use-imenu-flag (fboundp 'imenu)
- "*Non-nil means use imenu for file parsing. nil to use etags.
+ "*Non-nil means use imenu for file parsing, nil to use etags.
XEmacs prior to 20.4 doesn't support imenu, therefore the default is to
use etags instead. Etags support is not as robust as imenu support."
:tag "Use Imenu for tags"
(defcustom speedbar-use-tool-tips-flag (and (not (featurep 'xemacs))
(>= emacs-major-version 21))
- "*Non-nil means to use tool tips if they are avaialble.
+ "*Non-nil means to use tool tips if they are available.
When tooltips are not available, mouse-tracking and minibuffer
display is used instead."
:group 'speedbar
:type 'hook)
(defcustom speedbar-verbosity-level 1
- "*Verbosity level of the speedbar. 0 means say nothing.
-1 means medium level verbosity. 2 and higher are higher levels of
-verbosity."
+ "*Verbosity level of the speedbar.
+0 means say nothing.
+1 means medium level verbosity.
+2 and higher are higher levels of verbosity."
:group 'speedbar
:type 'integer)
"\\)$")))
(defvar speedbar-ignored-directory-regexp nil
- "Regular expression matching directorys speedbar will not switch to.
+ "Regular expression matching directories speedbar will not switch to.
Created from `speedbar-ignored-directory-expressions' with the function
`speedbar-extension-list-to-regex' (A misnamed function in this case.)
Use the function `speedbar-add-ignored-directory-regexp', or customize the
(defcustom speedbar-ignored-directory-expressions
'("[/\\]logs?[/\\]\\'")
"*List of regular expressions matching directories speedbar will ignore.
-They should included directorys to directories which are notoriously very
-large and take a long time to load in. Use the function
+They should included directories which are notoriously very large
+and take a long time to load in. Use the function
`speedbar-add-ignored-directory-regexp' to add new items to this list after
speedbar is loaded. You may place anything you like in this list
before speedbar has been loaded."
;; backup refdir lockfile
(concat nstr "\\|#[^#]+#$\\|\\.\\.?\\'\\|\\.#"))
"*Regexp matching files we don't want displayed in a speedbar buffer.
-It is generated from the variable `completion-ignored-extensions'")
+It is generated from the variable `completion-ignored-extensions'.")
(defvar speedbar-file-regexp nil
"Regular expression matching files we know how to expand.
Created from `speedbar-supported-extension-expressions' with the
-function `speedbar-extension-list-to-regex'")
+function `speedbar-extension-list-to-regex'.")
;; this is dangerous to customize, because the defaults will probably
;; change in the future.
singular expression. This variable will be turned into
`speedbar-file-regexp' for use with speedbar. You should use the
function `speedbar-add-supported-extension' to add a new extension at
-runtime, or use the configuration dialog to set it in your .emacs
-file.
+runtime, or use the configuration dialog to set it in your .emacs file.
If you add an extension to this list, and it does not appear, you may
need to also modify `completion-ignored-extension' which will also help
file completion."
(defun speedbar-handle-delete-frame (e)
"Handle a delete frame event E.
-If the deleted frame is the frame SPEEDBAR is attached to,
+If the deleted frame is the frame speedbar is attached to,
we need to delete speedbar also."
(when (and speedbar-frame
(eq (car (car (cdr e))) ;; frame to be deleted
speedbar-buffer)
(defmacro speedbar-message (fmt &rest args)
- "Like message, but for use in the speedbar frame.
+ "Like `message', but for use in the speedbar frame.
Argument FMT is the format string, and ARGS are the arguments for message."
`(dframe-message ,fmt ,@args))
(t (speedbar-message nil)))))))
(defun speedbar-show-info-under-mouse ()
- "Call the info function for the line under the mouse.
-Optional EVENT is currently not used."
+ "Call the info function for the line under the mouse."
(let ((pos (mouse-position))) ; we ignore event until I use it later.
(if (equal (car pos) speedbar-frame)
(save-excursion
(point) (progn (end-of-line) (point))))))
(defun speedbar-item-info ()
- "Display info in the mini-buffer about the button the mouse is over.
+ "Display info in the minibuffer about the button the mouse is over.
This function can be replaced in `speedbar-mode-functions-list' as
`speedbar-item-info'."
(interactive)
nil)))))
(defun speedbar-files-item-info ()
- "Display info in the mini-buffer about the button the mouse is over."
+ "Display info in the minibuffer about the button the mouse is over."
(if (not speedbar-shown-directories)
(speedbar-generic-item-info)
(or (speedbar-item-info-file-helper)
(speedbar-reconfigure-keymaps))))
(defun speedbar-fetch-replacement-function (function)
- "Return a current mode specific replacement for function, or nil.
+ "Return a current mode-specific replacement for function, or nil.
Scans `speedbar-mode-functions-list' first for the current mode, then
for FUNCTION."
(cdr (assoc function
;;
(defun speedbar-maybe-add-localized-support (buffer)
"Quick check function called on BUFFERs by the speedbar timer function.
-Maintains the value of local variables which control speedbars use
+Maintains the value of local variables which control speedbar's use
of the special mode functions."
(or speedbar-special-mode-expansion-list
(speedbar-add-localized-speedbar-support buffer)))
(defun speedbar-directory-buttons (directory index)
"Insert a single button group at point for DIRECTORY.
-Each directory directory part is a different button. If part of the directory
+Each directory part is a different button. If part of the directory
matches the user directory ~, then it is replaced with a ~.
INDEX is not used, but is required by the caller."
(let* ((tilde (expand-file-name "~/"))
)))
(defun speedbar-generic-list-positioned-group-p (sublst)
- "Non-nil of SUBLST is a group with a position."
+ "Non-nil if SUBLST is a group with a position."
(and (stringp (car-safe sublst))
(number-or-marker-p (car-safe (cdr-safe sublst)))
(listp (cdr-safe (cdr-safe sublst)))
"At LEVEL, insert a generic multi-level alist LST.
Associations with lists get {+} tags (to expand into more nodes) and
those with positions just get a > as the indicator. {+} buttons will
-have the function EXPAND-FUN and the token is the CDR list. The token
+have the function EXPAND-FUN and the token is the cdr list. The token
name will have the function FIND-FUN and not token."
;; Remove imenu rescan button
(if (string= (car (car lst)) "*Rescan*")
(defun speedbar-update-current-file ()
"Find the current file, and update our visuals to indicate its name.
This is specific to file names. If the file name doesn't show up, but
-it should be in the list, then the directory cache needs to be
-updated."
+it should be in the list, then the directory cache needs to be updated."
(let* ((lastf (selected-frame))
(newcfd (save-excursion
(dframe-select-attached-frame speedbar-frame)
(defun speedbar-add-indicator (indicator-string &optional replace-this)
"Add INDICATOR-STRING to the end of this speedbar line.
-If INDICATOR-STRING is space, and REPLACE-THIS is a character, then
-the existing indicator is removed. If there is already an
+If INDICATOR-STRING is space, and REPLACE-THIS is a character,
+then the existing indicator is removed. If there is already an
indicator, then do not add a space."
(beginning-of-line)
;; The nature of the beast: Assume we are in "the right place"
t)))
(defun speedbar-check-vc-this-line (depth)
- "Return t if the file on this line is check of of a version control system.
+ "Return t if the file on this line is checked out of a version control system.
Parameter DEPTH is a string with the current depth of indentation of
the file being checked."
(let* ((d (string-to-number depth))
(if rf (funcall rf depth) default-directory))))
(defun speedbar-files-line-directory (&optional depth)
- "Retrieve the directoryname associated with the current line.
+ "Retrieve the directory associated with the current line.
This may require traversing backwards from DEPTH and combining the default
directory with these items."
(save-excursion
(defun speedbar-tag-expand (text token indent)
"Expand a tag sublist. Imenu will return sub-lists of specialized tag types.
-Etags does not support this feature. TEXT will be the button
-string. TOKEN will be the list, and INDENT is the current indentation
-level."
+Etags does not support this feature. TEXT will be the button string.
+TOKEN will be the list, and INDENT is the current indentation level."
(cond ((string-match "+" text) ;we have to expand this file
(speedbar-change-expand-button-char ?-)
(speedbar-with-writable
; (delete-region (match-beginning 1) (match-end 1)))))
(defun speedbar-extract-one-symbol (expr)
- "At point, return nil, or one alist in the form: (SYMBOL . POSITION)
+ "At point, return nil, or one alist in the form (SYMBOL . POSITION)
The line should contain output from etags. Parse the output using the
regular expression EXPR."
(let* ((sym (if (stringp expr)
(defun speedbar-buffer-buttons (directory zero)
"Create speedbar buttons based on the buffers currently loaded.
-DIRECTORY is the directory to the currently active buffer, and ZERO is 0."
+DIRECTORY is the directory of the currently active buffer, and ZERO is 0."
(speedbar-buffer-buttons-engine nil))
(defun speedbar-buffer-buttons-temp (directory zero)
"Create speedbar buttons based on the buffers currently loaded.
-DIRECTORY is the directory to the currently active buffer, and ZERO is 0."
+DIRECTORY is the directory of the currently active buffer, and ZERO is 0."
(speedbar-buffer-buttons-engine t))
(defun speedbar-buffer-buttons-engine (temp)
(or (buffer-file-name buffer) "<No file>"))))))
(defun speedbar-buffers-line-directory (&optional depth)
- "Fetch the full directory to the file (buffer) specified on the current line.
+ "Fetch the directory to the file (buffer) specified on the current line.
Optional argument DEPTH specifies the current depth of the back search."
(save-excursion
(end-of-line)
(remove-hook 'pre-command-hook 'speedbar-unhighlight-one-tag-line))
(defun speedbar-recenter-to-top ()
- "Recenter the current buffer so POINT is on the top of the window."
+ "Recenter the current buffer so point is on the top of the window."
(recenter 1))
(defun speedbar-recenter ()
- "Recenter the current buffer so POINT is in the center of the window."
+ "Recenter the current buffer so point is in the center of the window."
(recenter (/ (window-height (selected-window)) 2)))
\f
(:background "white"
:foreground "black"
:overline "black")))
- "Face used for separator labes in a display."
+ "Face used for separator labels in a display."
:group 'speedbar-faces)
;; some edebug hooks
(make-obsolete 'focus-frame "it does nothing." "22.1")
(defalias 'unfocus-frame 'ignore "")
(make-obsolete 'unfocus-frame "it does nothing." "22.1")
-(make-obsolete 'make-variable-frame-local "use a frame-parameter instead." "22.2")
+(make-obsolete 'make-variable-frame-local
+ "explicitly check for a frame-parameter instead." "22.2")
\f
;;;; Obsolescence declarations for variables, and aliases.
If the optional third arg PATH is specified, that list of directories
is used instead of `load-path'.
-When called from a program, the file name is normaly returned as a
+When called from a program, the file name is normally returned as a
string. When run interactively, the argument INTERACTIVE-CALL is t,
and the file name is displayed in the echo area."
(interactive (list (completing-read "Locate library: "
(defvar temp-buffer-show-hook nil
"Normal hook run by `with-output-to-temp-buffer' after displaying the buffer.
When the hook runs, the temporary buffer is current, and the window it
-was displayed in is selected. This hook is normally set up with a
-function to make the buffer read only, and find function names and
-variable names in it, provided the major mode is still Help mode.")
+was displayed in is selected.")
(defvar temp-buffer-setup-hook nil
"Normal hook run by `with-output-to-temp-buffer' at the start.
;; (ck (tar-header-checksum tar-hblock))
(type (tar-header-link-type tar-hblock))
(link-name (tar-header-link-name tar-hblock)))
- (format "%c%c%s%8s/%-8s%7s%s %s%s"
+ (format "%c%c%s %7s/%-7s %7s%s %s%s"
(if mod-p ?* ? )
(cond ((or (eq type nil) (eq type 0)) ?-)
((eq type 1) ?h) ; link
(tar-header-block-tokenize
(buffer-substring pos (+ pos 512)))))))
(setq pos (+ pos 512))
+ (when (equal (tar-header-name tokens) "././@LongLink")
+ ;; This is a GNU Tar long-file-name header.
+ (let* ((size (tar-header-size tokens))
+ ;; -1 so as to strip the terminating 0 byte.
+ (name (buffer-substring pos (+ pos size -1))))
+ (setq pos (+ pos (ash (ash (+ 511 size) -9) 9)))
+ (setq tokens (tar-header-block-tokenize
+ (buffer-substring pos (+ pos 512))))
+ (tar-setf (tar-header-name tokens) name)
+ (setq pos (+ pos 512))))
(progress-reporter-update progress-reporter pos)
(if (memq (tar-header-link-type tokens) '(20 55))
;; Foo. There's an extra empty block after these.
(if (< size 0)
(error "%s has size %s - corrupted"
(tar-header-name tokens) size))
- ;
- ; This is just too slow. Don't really need it anyway....
- ;(tar-header-block-check-checksum
- ; hblock (tar-header-block-checksum hblock)
- ; (tar-header-name tokens))
+ ;;
+ ;; This is just too slow. Don't really need it anyway....
+ ;;(tar-header-block-check-checksum
+ ;; hblock (tar-header-block-checksum hblock)
+ ;; (tar-header-name tokens))
(push (make-tar-desc pos tokens) result)
(and (null (tar-header-link-type tokens))
(> size 0)
- (setq pos
- (+ pos 512 (ash (ash (1- size) -9) 9)) ; this works
- ;(+ pos (+ size (- 512 (rem (1- size) 512)))) ; this doesn't
- ))))
+ ;; Round up to a multiple of 512.
+ (setq pos (+ pos (ash (ash (+ 511 size) -9) 9))))))
(make-local-variable 'tar-parse-info)
(setq tar-parse-info (nreverse result))
;; A tar file should end with a block or two of nulls,
(defvar mac-apple-event-map)
(defvar mac-font-panel-mode)
(defvar mac-ts-active-input-overlay)
+(defvar mac-ts-active-input-buf)
(defvar x-invocation-args)
(defvar x-command-line-resources nil)
(setq modifiers (cons (car modifier-mask) modifiers)))))
modifiers))
+(defun mac-ae-reopen-application (event)
+ "Show some frame in response to the Apple event EVENT.
+The frame to be shown is chosen from visible or iconified frames
+if possible. If there's no such frame, a new frame is created."
+ (interactive "e")
+ (unless (frame-visible-p (selected-frame))
+ (let ((frame (or (car (visible-frame-list))
+ (car (filtered-frame-list 'frame-visible-p)))))
+ (if frame
+ (select-frame frame)
+ (switch-to-buffer-other-frame "*scratch*"))))
+ (select-frame-set-input-focus (selected-frame)))
+
(defun mac-ae-open-documents (event)
"Open the documents specified by the Apple event EVENT."
(interactive "e")
(let ((line (car selection-range))
(start (cadr selection-range))
(end (nth 2 selection-range)))
- (if (> line 0)
- (goto-line line)
- (if (and (> start 0) (> end 0))
- (progn (set-mark start)
- (goto-char end))))))
+ (if (>= line 0)
+ (goto-line (1+ line))
+ (if (and (>= start 0) (>= end 0))
+ (progn (set-mark (1+ start))
+ (goto-char (1+ end)))))))
((stringp search-text)
(re-search-forward
(mapconcat 'regexp-quote (split-string search-text) "\\|")
(define-key mac-apple-event-map [core-event open-application] 0)
;; Received when a dock or application icon is clicked and Emacs is
-;; already running. Simply ignored. Another idea is to make a new
-;; frame if all frames are invisible.
-(define-key mac-apple-event-map [core-event reopen-application] 'ignore)
+;; already running.
+(define-key mac-apple-event-map [core-event reopen-application]
+ 'mac-ae-reopen-application)
(define-key mac-apple-event-map [core-event open-documents]
'mac-ae-open-documents)
) ;; (fboundp 'mac-set-font-panel-visible-p)
;;; Text Services
-(defvar mac-ts-active-input-buf ""
- "Byte sequence of the current Mac TSM active input area.")
(defvar mac-ts-update-active-input-area-seqno 0
"Number of processed update-active-input-area events.")
(setq mac-ts-active-input-overlay (make-overlay 0 0))
(handler (cdr type-info))
(w (posn-window (event-start event))))
(when handler
- (if (and (windowp w) (window-live-p w)
+ (if (and (window-live-p w)
(not (window-minibuffer-p w))
(not (window-dedicated-p w)))
;; If dropping in an ordinary window which we could use,
(cons (cons 'enriched-mode enriched-mode-map)
minor-mode-map-alist)))
-(define-key enriched-mode-map "\C-a" 'beginning-of-line-text)
+(define-key enriched-mode-map [remap move-beginning-of-line] 'beginning-of-line-text)
(define-key enriched-mode-map "\C-m" 'reindent-then-newline-and-indent)
-(define-key enriched-mode-map "\C-j" 'reindent-then-newline-and-indent)
+(define-key enriched-mode-map
+ [remap newline-and-indent] 'reindent-then-newline-and-indent)
(define-key enriched-mode-map "\M-j" 'facemenu-justification-menu)
(define-key enriched-mode-map "\M-S" 'set-justification-center)
(define-key enriched-mode-map "\C-x\t" 'increase-left-margin)
If ARG is non-nil (interactively, with prefix argument), justify as well.
If `sentence-end-double-space' is non-nil, then period followed by one
space does not end a sentence, so don't break a line there.
-the variable `fill-column' controls the width for filling.
+The variable `fill-column' controls the width for filling.
If `fill-paragraph-function' is non-nil, we call it (passing our
argument to it), and if it returns non-nil, we simply return its value.
;; this is done, we can start checking...
(if flyspell-issue-message-flag (message "Checking region..."))
(set-buffer curbuf)
- (ispell-check-version)
+ (ispell-maybe-find-aspell-dictionaries)
(let ((c (apply 'ispell-call-process-region beg
end
ispell-program-name
(defun flyspell-region (beg end)
"Flyspell text between BEG and END."
(interactive "r")
+ (ispell-maybe-find-aspell-dictionaries)
(if (= beg end)
()
(save-excursion
--- /dev/null
+;;; org-export-latex.el --- LaTeX exporter for org-mode
+;;
+;; Copyright (c) 2007, 2008 Free Software Foundation, Inc.
+;;
+;; Emacs Lisp Archive Entry
+;; Filename: org-export-latex.el
+;; Version: 5.23
+;; Author: Bastien Guerry <bzg AT altern DOT org>
+;; Maintainer: Bastien Guerry <bzg AT altern DOT org>
+;; Keywords: org, wp, tex
+;; Description: Converts an org-mode buffer into LaTeX
+;; URL: http://www.cognition.ens.fr/~guerry/u/org-export-latex.el
+;;
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by the
+;; Free Software Foundation; either version 3, or (at your option) any
+;; later version.
+;;
+;; GNU Emacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+;; MA 02110-1301, USA.
+;;
+;;; Commentary:
+;;
+;; This library implements a LaTeX exporter for org-mode.
+;;
+;; Put this file into your load-path and the following into your ~/.emacs:
+;; (require 'org-export-latex)
+;;
+;; The interactive functions are similar to those of the HTML exporter:
+;;
+;; M-x `org-export-as-latex'
+;; M-x `org-export-as-latex-batch'
+;; M-x `org-export-as-latex-to-buffer'
+;; M-x `org-export-region-as-latex'
+;; M-x `org-replace-region-by-latex'
+;;
+;;; Code:
+
+(eval-when-compile
+ (require 'cl))
+
+(require 'footnote)
+(require 'org)
+
+;;; Variables:
+(defvar org-export-latex-class nil)
+(defvar org-export-latex-header nil)
+(defvar org-export-latex-append-header nil)
+(defvar org-export-latex-options-plist nil)
+(defvar org-export-latex-todo-keywords-1 nil)
+(defvar org-export-latex-all-targets-re nil)
+(defvar org-export-latex-add-level 0)
+(defvar org-export-latex-sectioning "")
+(defvar org-export-latex-sectioning-depth 0)
+(defvar org-export-latex-list-beginning-re
+ "^\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) +?")
+
+(defvar org-export-latex-special-string-regexps
+ '(org-ts-regexp
+ org-scheduled-string
+ org-deadline-string
+ org-clock-string)
+ "A list of regexps to convert as special keywords.")
+
+(defvar latexp) ; dynamically scoped from org.el
+(defvar re-quote) ; dynamically scoped from org.el
+(defvar commentsp) ; dynamically scoped from org.el
+
+;;; User variables:
+
+(defcustom org-export-latex-default-class "article"
+ "The default LaTeX class."
+ :group 'org-export-latex
+ :type '(string :tag "LaTeX class"))
+
+(defcustom org-export-latex-classes
+ '(("article"
+ "\\documentclass[11pt,a4paper]{article}
+\\usepackage[utf8]{inputenc}
+\\usepackage[T1]{fontenc}
+\\usepackage{hyperref}"
+ ("\\section{%s}" . "\\section*{%s}")
+ ("\\subsection{%s}" . "\\subsection*{%s}")
+ ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
+ ("\\paragraph{%s}" . "\\paragraph*{%s}")
+ ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
+ ("report"
+ "\\documentclass[11pt,a4paper]{report}
+\\usepackage[utf8]{inputenc}
+\\usepackage[T1]{fontenc}
+\\usepackage{hyperref}"
+ ("\\part{%s}" . "\\part*{%s}")
+ ("\\chapter{%s}" . "\\chapter*{%s}")
+ ("\\section{%s}" . "\\section*{%s}")
+ ("\\subsection{%s}" . "\\subsection*{%s}")
+ ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))
+ ("book"
+ "\\documentclass[11pt,a4paper]{book}
+\\usepackage[utf8]{inputenc}
+\\usepackage[T1]{fontenc}
+\\usepackage{hyperref}"
+ ("\\part{%s}" . "\\part*{%s}")
+ ("\\chapter{%s}" . "\\chapter*{%s}")
+ ("\\section{%s}" . "\\section*{%s}")
+ ("\\subsection{%s}" . "\\subsection*{%s}")
+ ("\\subsubsection{%s}" . "\\subsubsection*{%s}")))
+ "Alist of LaTeX classes and associated header and structure.
+If #+LaTeX_CLASS is set in the buffer, use its value and the
+associated information. Here is the structure of each cell:
+
+ \(class-name
+ header-string
+ (unnumbered-section numbered-section\)
+ ...\)
+
+A %s formatter is mandatory in each section string and will be
+replaced by the title of the section."
+ :group 'org-export-latex
+ :type '(repeat
+ (list (string :tag "LaTeX class")
+ (string :tag "LaTeX header")
+ (cons :tag "Level 1"
+ (string :tag "Numbered")
+ (string :tag "Unnumbered"))
+ (cons :tag "Level 2"
+ (string :tag "Numbered")
+ (string :tag "Unnumbered"))
+ (cons :tag "Level 3"
+ (string :tag "Numbered")
+ (string :tag "Unnumbered"))
+ (cons :tag "Level 4"
+ (string :tag "Numbered")
+ (string :tag "Unnumbered"))
+ (cons :tag "Level 5"
+ (string :tag "Numbered")
+ (string :tag "Unnumbered")))))
+
+(defcustom org-export-latex-emphasis-alist
+ '(("*" "\\textbf{%s}" nil)
+ ("/" "\\emph{%s}" nil)
+ ("_" "\\underline{%s}" nil)
+ ("+" "\\texttt{%s}" nil)
+ ("=" "\\texttt{%s}" nil)
+ ("~" "\\texttt{%s}" t))
+ "Alist of LaTeX expressions to convert emphasis fontifiers.
+Each element of the list is a list of three elements.
+The first element is the character used as a marker for fontification.
+The second element is a formatting string to wrap fontified text with.
+The third element decides whether to protect converted text from other
+conversions."
+ :group 'org-export-latex
+ :type 'alist)
+
+(defcustom org-export-latex-title-command "\\maketitle"
+ "The command used to insert the title just after \\begin{document}.
+If this string contains the formatting specification \"%s\" then
+it will be used as a formatting string, passing the title as an
+argument."
+ :group 'org-export-latex
+ :type 'string)
+
+(defcustom org-export-latex-date-format
+ "%d %B %Y"
+ "Format string for \\date{...}."
+ :group 'org-export-latex
+ :type 'string)
+
+(defcustom org-export-latex-tables-verbatim nil
+ "When non-nil, export tables as verbatim."
+ :group 'org-export-latex
+ :type 'boolean)
+
+(defcustom org-export-latex-tables-column-borders nil
+ "When non-nil, group of columns are surrounded with borders,
+XSeven if these borders are the outside borders of the table."
+ :group 'org-export-latex
+ :type 'boolean)
+
+(defcustom org-export-latex-packages-alist nil
+ "Alist of packages to be inserted in the header.
+Each cell is of the forma \( \"option\" . \"package\" \)."
+ :group 'org-export-latex
+ :type 'alist)
+
+(defcustom org-export-latex-low-levels 'description
+ "How to convert sections below the current level of sectioning,
+as specified by `org-export-headline-levels' or the value of \"H:\"
+in Org's #+OPTION line.
+
+This can be either nil (skip the sections), 'description (convert
+the sections as descriptive lists) or a string to be used instead
+of \\section{%s}. In this latter case, the %s stands here for the
+inserted headline and is mandatory."
+ :group 'org-export-latex
+ :type '(choice (const :tag "Ignore" nil)
+ (symbol :tag "Convert as descriptive list" description)
+ (string :tag "Use a section string" :value "\\subparagraph{%s}")))
+
+(defcustom org-export-latex-remove-from-headlines
+ '(:todo t :priority t :tags t)
+ "A plist of keywords to remove from headlines.
+Non-nil means remove this keyword type from the headline.
+
+Don't remove the keys, just change their values."
+ :type 'plist
+ :group 'org-export-latex)
+
+(defcustom org-export-latex-image-default-option "width=10em"
+ "Default option for images."
+ :group 'org-export-latex
+ :type 'string)
+
+(defcustom org-export-latex-coding-system nil
+ "Coding system for the exported LaTex file."
+ :group 'org-export-latex
+ :type 'coding-system)
+
+(defcustom org-list-radio-list-templates
+ '((latex-mode "% BEGIN RECEIVE ORGLST %n
+% END RECEIVE ORGLST %n
+\\begin{comment}
+#+ORGLST: SEND %n org-list-to-latex
+| | |
+\\end{comment}\n")
+ (texinfo-mode "@c BEGIN RECEIVE ORGLST %n
+@c END RECEIVE ORGLST %n
+@ignore
+#+ORGLST: SEND %n org-list-to-texinfo
+| | |
+@end ignore\n")
+ (html-mode "<!-- BEGIN RECEIVE ORGLST %n -->
+<!-- END RECEIVE ORGLST %n -->
+<!--
+#+ORGLST: SEND %n org-list-to-html
+| | |
+-->\n"))
+ "Templates for radio lists in different major modes.
+All occurrences of %n in a template will be replaced with the name of the
+list, obtained by prompting the user."
+ :group 'org-plain-lists
+ :type '(repeat
+ (list (symbol :tag "Major mode")
+ (string :tag "Format"))))
+
+;;; Autoload functions:
+
+;;;###autoload
+(defun org-export-as-latex-batch ()
+ "Call `org-export-as-latex', may be used in batch processing as
+emacs --batch
+ --load=$HOME/lib/emacs/org.el
+ --eval \"(setq org-export-headline-levels 2)\"
+ --visit=MyFile --funcall org-export-as-latex-batch"
+ (org-export-as-latex org-export-headline-levels 'hidden))
+
+;;;###autoload
+(defun org-export-as-latex-to-buffer (arg)
+ "Call `org-exort-as-latex` with output to a temporary buffer.
+No file is created. The prefix ARG is passed through to `org-export-as-latex'."
+ (interactive "P")
+ (org-export-as-latex arg nil nil "*Org LaTeX Export*")
+ (switch-to-buffer-other-window "*Org LaTeX Export*"))
+
+;;;###autoload
+(defun org-replace-region-by-latex (beg end)
+ "Replace the region from BEG to END with its LaTeX export.
+It assumes the region has `org-mode' syntax, and then convert it to
+LaTeX. This can be used in any buffer. For example, you could
+write an itemized list in `org-mode' syntax in an LaTeX buffer and
+then use this command to convert it."
+ (interactive "r")
+ (let (reg latex buf)
+ (save-window-excursion
+ (if (org-mode-p)
+ (setq latex (org-export-region-as-latex
+ beg end t 'string))
+ (setq reg (buffer-substring beg end)
+ buf (get-buffer-create "*Org tmp*"))
+ (save-excursion
+ (set-buffer buf)
+ (erase-buffer)
+ (insert reg)
+ (org-mode)
+ (setq latex (org-export-region-as-latex
+ (point-min) (point-max) t 'string)))
+ (kill-buffer buf)))
+ (delete-region beg end)
+ (insert latex)))
+
+;;;###autoload
+(defun org-export-region-as-latex (beg end &optional body-only buffer)
+ "Convert region from BEG to END in `org-mode' buffer to LaTeX.
+If prefix arg BODY-ONLY is set, omit file header, footer, and table of
+contents, and only produce the region of converted text, useful for
+cut-and-paste operations.
+If BUFFER is a buffer or a string, use/create that buffer as a target
+of the converted LaTeX. If BUFFER is the symbol `string', return the
+produced LaTeX as a string and leave not buffer behind. For example,
+a Lisp program could call this function in the following way:
+
+ (setq latex (org-export-region-as-latex beg end t 'string))
+
+When called interactively, the output buffer is selected, and shown
+in a window. A non-interactive call will only retunr the buffer."
+ (interactive "r\nP")
+ (when (interactive-p)
+ (setq buffer "*Org LaTeX Export*"))
+ (let ((transient-mark-mode t) (zmacs-regions t)
+ rtn)
+ (goto-char end)
+ (set-mark (point)) ;; to activate the region
+ (goto-char beg)
+ (setq rtn (org-export-as-latex
+ nil nil nil
+ buffer body-only))
+ (if (fboundp 'deactivate-mark) (deactivate-mark))
+ (if (and (interactive-p) (bufferp rtn))
+ (switch-to-buffer-other-window rtn)
+ rtn)))
+
+;;;###autoload
+(defun org-export-as-latex (arg &optional hidden ext-plist
+ to-buffer body-only pub-dir)
+ "Export current buffer to a LaTeX file.
+If there is an active region, export only the region. The prefix
+ARG specifies how many levels of the outline should become
+headlines. The default is 3. Lower levels will be exported
+depending on `org-export-latex-low-levels'. The default is to
+convert them as description lists. When HIDDEN is non-nil, don't
+display the LaTeX buffer. EXT-PLIST is a property list with
+external parameters overriding org-mode's default settings, but
+still inferior to file-local settings. When TO-BUFFER is
+non-nil, create a buffer with that name and export to that
+buffer. If TO-BUFFER is the symbol `string', don't leave any
+buffer behind but just return the resulting LaTeX as a string.
+When BODY-ONLY is set, don't produce the file header and footer,
+simply return the content of \begin{document}...\end{document},
+without even the \begin{document} and \end{document} commands.
+when PUB-DIR is set, use this as the publishing directory."
+ (interactive "P")
+ ;; Make sure we have a file name when we need it.
+ (when (and (not (or to-buffer body-only))
+ (not buffer-file-name))
+ (if (buffer-base-buffer)
+ (org-set-local 'buffer-file-name
+ (with-current-buffer (buffer-base-buffer)
+ buffer-file-name))
+ (error "Need a file name to be able to export")))
+
+ (message "Exporting to LaTeX...")
+ (org-update-radio-target-regexp)
+ (org-export-latex-set-initial-vars ext-plist arg)
+ (let* ((wcf (current-window-configuration))
+ (opt-plist org-export-latex-options-plist)
+ (region-p (org-region-active-p))
+ (subtree-p
+ (when region-p
+ (save-excursion
+ (goto-char (region-beginning))
+ (and (org-at-heading-p)
+ (>= (org-end-of-subtree t t) (region-end))))))
+ (title (or (and subtree-p (org-export-get-title-from-subtree))
+ (plist-get opt-plist :title)
+ (and (not
+ (plist-get opt-plist :skip-before-1st-heading))
+ (org-export-grab-title-from-buffer))
+ (file-name-sans-extension
+ (file-name-nondirectory buffer-file-name))))
+ (filename (concat (file-name-as-directory
+ (or pub-dir
+ (org-export-directory :LaTeX ext-plist)))
+ (file-name-sans-extension
+ (file-name-nondirectory ;sans-extension
+ buffer-file-name)) ".tex"))
+ (filename (if (equal (file-truename filename)
+ (file-truename buffer-file-name))
+ (concat filename ".tex")
+ filename))
+ (buffer (if to-buffer
+ (cond
+ ((eq to-buffer 'string) (get-buffer-create
+ "*Org LaTeX Export*"))
+ (t (get-buffer-create to-buffer)))
+ (find-file-noselect filename)))
+ (odd org-odd-levels-only)
+ (header (org-export-latex-make-header title opt-plist))
+ (skip (cond (subtree-p nil)
+ (region-p t)
+ ;; never skip first lines when exporting a subtree
+ (t (plist-get opt-plist :skip-before-1st-heading))))
+ (text (plist-get opt-plist :text))
+ (first-lines (if skip "" (org-export-latex-first-lines)))
+ (coding-system (and (boundp 'buffer-file-coding-system)
+ buffer-file-coding-system))
+ (coding-system-for-write (or org-export-latex-coding-system
+ coding-system))
+ (save-buffer-coding-system (or org-export-latex-coding-system
+ coding-system))
+ (region (buffer-substring
+ (if region-p (region-beginning) (point-min))
+ (if region-p (region-end) (point-max))))
+ (string-for-export
+ (org-cleaned-string-for-export
+ region :emph-multiline t
+ :for-LaTeX t
+ :comments nil
+ :add-text (if (eq to-buffer 'string) nil text)
+ :skip-before-1st-heading skip
+ :LaTeX-fragments nil)))
+
+ (set-buffer buffer)
+ (erase-buffer)
+
+ (and (fboundp 'set-buffer-file-coding-system)
+ (set-buffer-file-coding-system coding-system-for-write))
+
+ ;; insert the header and initial document commands
+ (unless (or (eq to-buffer 'string) body-only)
+ (insert header))
+
+ ;; insert text found in #+TEXT
+ (when (and text (not (eq to-buffer 'string)))
+ (insert (org-export-latex-content
+ text '(lists tables fixed-width keywords))
+ "\n\n"))
+
+ ;; insert lines before the first headline
+ (unless (or skip (eq to-buffer 'string))
+ (insert first-lines))
+
+ ;; handle the case where the region does not begin with a section
+ (when region-p
+ (insert (with-temp-buffer
+ (insert string-for-export)
+ (org-export-latex-first-lines))))
+
+ ;; export the content of headlines
+ (org-export-latex-global
+ (with-temp-buffer
+ (insert string-for-export)
+ (goto-char (point-min))
+ (when (re-search-forward "^\\(\\*+\\) " nil t)
+ (let* ((asters (length (match-string 1)))
+ (level (if odd (- asters 2) (- asters 1))))
+ (setq org-export-latex-add-level
+ (if odd (1- (/ (1+ asters) 2)) (1- asters)))
+ (org-export-latex-parse-global level odd)))))
+
+ ;; finalization
+ (unless body-only (insert "\n\\end{document}"))
+ (or to-buffer (save-buffer))
+ (goto-char (point-min))
+ (message "Exporting to LaTeX...done")
+ (prog1
+ (if (eq to-buffer 'string)
+ (prog1 (buffer-substring (point-min) (point-max))
+ (kill-buffer (current-buffer)))
+ (current-buffer))
+ (set-window-configuration wcf))))
+
+;;; Parsing functions:
+
+(defun org-export-latex-parse-global (level odd)
+ "Parse the current buffer recursively, starting at LEVEL.
+If ODD is non-nil, assume the buffer only contains odd sections.
+Return a list reflecting the document structure."
+ (save-excursion
+ (goto-char (point-min))
+ (let* ((cnt 0) output
+ (depth org-export-latex-sectioning-depth))
+ (while (re-search-forward
+ (concat "^\\(\\(?:\\*\\)\\{"
+ (number-to-string (+ (if odd 2 1) level))
+ "\\}\\) \\(.*\\)$")
+ ;; make sure that there is no upper heading
+ (when (> level 0)
+ (save-excursion
+ (save-match-data
+ (re-search-forward
+ (concat "^\\(\\(?:\\*\\)\\{"
+ (number-to-string level)
+ "\\}\\) \\(.*\\)$") nil t)))) t)
+ (setq cnt (1+ cnt))
+ (let* ((pos (match-beginning 0))
+ (heading (match-string 2))
+ (nlevel (if odd (/ (+ 3 level) 2) (1+ level))))
+ (save-excursion
+ (narrow-to-region
+ (point)
+ (save-match-data
+ (if (re-search-forward
+ (concat "^\\(\\(?:\\*\\)\\{"
+ (number-to-string (+ (if odd 2 1) level))
+ "\\}\\) \\(.*\\)$") nil t)
+ (match-beginning 0)
+ (point-max))))
+ (goto-char (point-min))
+ (setq output
+ (append output
+ (list
+ (list
+ `(pos . ,pos)
+ `(level . ,nlevel)
+ `(occur . ,cnt)
+ `(heading . ,heading)
+ `(content . ,(org-export-latex-parse-content))
+ `(subcontent . ,(org-export-latex-parse-subcontent
+ level odd)))))))
+ (widen)))
+ (list output))))
+
+(defun org-export-latex-parse-content ()
+ "Extract the content of a section."
+ (let ((beg (point))
+ (end (if (re-search-forward "^\\(\\*\\)+ .*$" nil t)
+ (progn (beginning-of-line) (point))
+ (point-max))))
+ (buffer-substring beg end)))
+
+(defun org-export-latex-parse-subcontent (level odd)
+ "Extract the subcontent of a section at LEVEL.
+If ODD Is non-nil, assume subcontent only contains odd sections."
+ (if (not (re-search-forward
+ (concat "^\\(\\(?:\\*\\)\\{"
+ (number-to-string (+ (if odd 4 2) level))
+ "\\}\\) \\(.*\\)$")
+ nil t))
+ nil ; subcontent is nil
+ (org-export-latex-parse-global (+ (if odd 2 1) level) odd)))
+
+;;; Rendering functions:
+(defun org-export-latex-global (content)
+ "Export CONTENT to LaTeX.
+CONTENT is an element of the list produced by
+`org-export-latex-parse-global'."
+ (if (eq (car content) 'subcontent)
+ (mapc 'org-export-latex-sub (cdr content))
+ (org-export-latex-sub (car content))))
+
+(defun org-export-latex-sub (subcontent)
+ "Export the list SUBCONTENT to LaTeX.
+SUBCONTENT is an alist containing information about the headline
+and its content."
+ (let ((num (plist-get org-export-latex-options-plist :section-numbers)))
+ (mapc (lambda(x) (org-export-latex-subcontent x num)) subcontent)))
+
+(defun org-export-latex-subcontent (subcontent num)
+ "Export each cell of SUBCONTENT to LaTeX."
+ (let ((heading (org-export-latex-fontify-headline
+ (cdr (assoc 'heading subcontent))))
+ (level (- (cdr (assoc 'level subcontent))
+ org-export-latex-add-level))
+ (occur (number-to-string (cdr (assoc 'occur subcontent))))
+ (content (cdr (assoc 'content subcontent)))
+ (subcontent (cadr (assoc 'subcontent subcontent))))
+ (cond
+ ;; Normal conversion
+ ((<= level org-export-latex-sectioning-depth)
+ (let ((sec (nth (1- level) org-export-latex-sectioning)))
+ (insert (format (if num (car sec) (cdr sec)) heading) "\n"))
+ (insert (org-export-latex-content content))
+ (cond ((stringp subcontent) (insert subcontent))
+ ((listp subcontent) (org-export-latex-sub subcontent))))
+ ;; At a level under the hl option: we can drop this subsection
+ ((> level org-export-latex-sectioning-depth)
+ (cond ((eq org-export-latex-low-levels 'description)
+ (insert (format "\\begin{description}\n\n\\item[%s]\n\n" heading))
+ (insert (org-export-latex-content content))
+ (cond ((stringp subcontent) (insert subcontent))
+ ((listp subcontent) (org-export-latex-sub subcontent)))
+ (insert "\\end{description}\n"))
+ ((stringp org-export-latex-low-levels)
+ (insert (format org-export-latex-low-levels heading) "\n")
+ (insert (org-export-latex-content content))
+ (cond ((stringp subcontent) (insert subcontent))
+ ((listp subcontent) (org-export-latex-sub subcontent)))))))))
+
+;;; Exporting internals:
+(defun org-export-latex-set-initial-vars (ext-plist level)
+ "Store org local variables required for LaTeX export.
+EXT-PLIST is an optional additional plist.
+LEVEL indicates the default depth for export."
+ (setq org-export-latex-todo-keywords-1 org-todo-keywords-1
+ org-export-latex-all-targets-re
+ (org-make-target-link-regexp (org-all-targets))
+ org-export-latex-options-plist
+ (org-combine-plists (org-default-export-plist) ext-plist
+ (org-infile-export-plist))
+ org-export-latex-class
+ (save-excursion
+ (goto-char (point-min))
+ (if (and (re-search-forward "^#\\+LaTeX_CLASS:[ \t]*\\([a-zA-Z]+\\)" nil t)
+ (assoc (match-string 1) org-export-latex-classes))
+ (match-string 1)
+ org-export-latex-default-class))
+ org-export-latex-header
+ (cadr (assoc org-export-latex-class org-export-latex-classes))
+ org-export-latex-sectioning
+ (cddr (assoc org-export-latex-class org-export-latex-classes))
+ org-export-latex-sectioning-depth
+ (or level
+ (let ((hl-levels
+ (plist-get org-export-latex-options-plist :headline-levels))
+ (sec-depth (length org-export-latex-sectioning)))
+ (if (> hl-levels sec-depth) sec-depth hl-levels)))))
+
+(defun org-export-latex-make-header (title opt-plist)
+ "Make the LaTeX header and return it as a string.
+TITLE is the current title from the buffer or region.
+OPT-PLIST is the options plist for current buffer."
+ (let ((toc (plist-get opt-plist :table-of-contents))
+ (author (plist-get opt-plist :author)))
+ (concat
+ (if (plist-get opt-plist :time-stamp-file)
+ (format-time-string "% Created %Y-%m-%d %a %H:%M\n"))
+ ;; insert LaTeX custom header
+ org-export-latex-header
+ "\n"
+ ;; insert information on LaTeX packages
+ (when org-export-latex-packages-alist
+ (mapconcat (lambda(p)
+ (if (equal "" (car p))
+ (format "\\usepackage{%s}" (cadr p))
+ (format "\\usepackage[%s]{%s}"
+ (car p) (cadr p))))
+ org-export-latex-packages-alist "\n"))
+ ;; insert additional commands in the header
+ org-export-latex-append-header
+ ;; insert the title
+ (format
+ "\n\n\\title{%s}\n"
+ ;; convert the title
+ (org-export-latex-content
+ title '(lists tables fixed-width keywords)))
+ ;; insert author info
+ (if (plist-get opt-plist :author-info)
+ (format "\\author{%s}\n"
+ (or author user-full-name))
+ (format "%%\\author{%s}\n"
+ (or author user-full-name)))
+ ;; insert the date
+ (format "\\date{%s}\n"
+ (format-time-string
+ (or (plist-get opt-plist :date)
+ org-export-latex-date-format)))
+ ;; beginning of the document
+ "\n\\begin{document}\n\n"
+ ;; insert the title command
+ (if (string-match "%s" org-export-latex-title-command)
+ (format org-export-latex-title-command title)
+ org-export-latex-title-command)
+ "\n\n"
+ ;; table of contents
+ (when (and org-export-with-toc
+ (plist-get opt-plist :section-numbers))
+ (cond ((numberp toc)
+ (format "\\setcounter{tocdepth}{%s}\n\\tableofcontents\n\n"
+ (min toc (plist-get opt-plist :headline-levels))))
+ (toc (format "\\setcounter{tocdepth}{%s}\n\\tableofcontents\n\n"
+ (plist-get opt-plist :headline-levels))))))))
+
+(defun org-export-latex-first-lines (&optional comments)
+ "Export the first lines before first headline.
+COMMENTS is either nil to replace them with the empty string or a
+formatting string like %%%%s if we want to comment them out."
+ (save-excursion
+ (goto-char (point-min))
+ (if (org-at-heading-p) (beginning-of-line 2))
+ (let* ((pt (point))
+ (end (if (and (re-search-forward "^\\* " nil t)
+ (not (eq pt (match-beginning 0))))
+ (goto-char (match-beginning 0))
+ (goto-char (point-max)))))
+ (org-export-latex-content
+ (org-cleaned-string-for-export
+ (buffer-substring (point-min) end)
+ :for-LaTeX t
+ :emph-multiline t
+ :add-text nil
+ :comments nil
+ :skip-before-1st-heading nil
+ :LaTeX-fragments nil)))))
+
+(defun org-export-latex-content (content &optional exclude-list)
+ "Convert CONTENT string to LaTeX.
+Don't perform conversions that are in EXCLUDE-LIST. Recognized
+conversion types are: quotation-marks, emphasis, sub-superscript,
+links, keywords, lists, tables, fixed-width"
+ (with-temp-buffer
+ (insert content)
+ (unless (memq 'quotation-marks exclude-list)
+ (org-export-latex-quotation-marks))
+ (unless (memq 'emphasis exclude-list)
+ (when (plist-get org-export-latex-options-plist :emphasize)
+ (org-export-latex-fontify)))
+ (unless (memq 'sub-superscript exclude-list)
+ (org-export-latex-special-chars
+ (plist-get org-export-latex-options-plist :sub-superscript)))
+ (unless (memq 'links exclude-list)
+ (org-export-latex-links))
+ (unless (memq 'keywords exclude-list)
+ (org-export-latex-keywords
+ (plist-get org-export-latex-options-plist :timestamps)))
+ (unless (memq 'lists exclude-list)
+ (org-export-latex-lists))
+ (unless (memq 'tables exclude-list)
+ (org-export-latex-tables
+ (plist-get org-export-latex-options-plist :tables)))
+ (unless (memq 'fixed-width exclude-list)
+ (org-export-latex-fixed-width
+ (plist-get org-export-latex-options-plist :fixed-width)))
+ ;; return string
+ (buffer-substring (point-min) (point-max))))
+
+(defun org-export-latex-protect-string (s)
+ "Prevent further conversion for string S by adding the
+org-protect property."
+ (add-text-properties 0 (length s) '(org-protected t) s) s)
+
+(defun org-export-latex-protect-char-in-string (char-list string)
+ "Add org-protected text-property to char from CHAR-LIST in STRING."
+ (with-temp-buffer
+ (save-match-data
+ (insert string)
+ (goto-char (point-min))
+ (while (re-search-forward (regexp-opt char-list) nil t)
+ (add-text-properties (match-beginning 0)
+ (match-end 0) '(org-protected t)))
+ (buffer-string))))
+
+(defun org-export-latex-keywords-maybe (remove-list)
+ "Maybe remove keywords depending on rules in REMOVE-LIST."
+ (goto-char (point-min))
+ (let ((re-todo (mapconcat 'identity org-export-latex-todo-keywords-1 "\\|"))
+ (case-fold-search nil))
+ ;; convert TODO keywords
+ (when (re-search-forward (concat "^\\(" re-todo "\\)") nil t)
+ (if (plist-get remove-list :todo)
+ (replace-match "")
+ (replace-match (format "\\texttt{%s}" (match-string 1)) t t)))
+ ;; convert priority string
+ (when (re-search-forward "\\[\\\\#.\\]" nil t)
+ (if (plist-get remove-list :priority)
+ (replace-match "")
+ (replace-match (format "\\texttt{%s}" (match-string 0)) t t)))
+ ;; convert tags
+ (when (re-search-forward "\\(:[a-zA-Z0-9]+\\)+:" nil t)
+ (if (or (not org-export-with-tags)
+ (plist-get remove-list :tags))
+ (replace-match "")
+ (replace-match (format "\\texttt{%s}" (match-string 0)) t t)))))
+
+(defun org-export-latex-fontify-headline (string)
+ "Fontify special words in string."
+ (with-temp-buffer
+ ;; FIXME: org-inside-LaTeX-fragment-p doesn't work when the $...$ is at
+ ;; the beginning of the buffer - inserting "\n" is safe here though.
+ (insert "\n" string)
+ (goto-char (point-min))
+ (when (plist-get org-export-latex-options-plist :emphasize)
+ (org-export-latex-fontify))
+ (org-export-latex-special-chars
+ (plist-get org-export-latex-options-plist :sub-superscript))
+ (org-export-latex-keywords-maybe
+ org-export-latex-remove-from-headlines)
+ (org-export-latex-links)
+ (org-trim (buffer-substring-no-properties (point-min) (point-max)))))
+
+(defun org-export-latex-quotation-marks ()
+ "Export question marks depending on language conventions."
+ (let* ((lang (plist-get org-export-latex-options-plist :language))
+ (quote-rpl (if (equal lang "fr")
+ '(("\\(\\s-\\)\"" "«~")
+ ("\\(\\S-\\)\"" "~»")
+ ("\\(\\s-\\)'" "`"))
+ '(("\\(\\s-\\)\"" "``")
+ ("\\(\\S-\\)\"" "''")
+ ("\\(\\s-\\)'" "`")))))
+ (mapc (lambda(l) (goto-char (point-min))
+ (while (re-search-forward (car l) nil t)
+ (let ((rpl (concat (match-string 1) (cadr l))))
+ (org-export-latex-protect-string rpl)
+ (org-if-unprotected
+ (replace-match rpl t t))))) quote-rpl)))
+
+(defun org-export-latex-special-chars (sub-superscript)
+ "Export special characters to LaTeX.
+If SUB-SUPERSCRIPT is non-nil, convert \\ and ^.
+See the `org-export-latex.el' code for a complete conversion table."
+ (goto-char (point-min))
+ (mapc (lambda(c)
+ (goto-char (point-min))
+ (while (re-search-forward c nil t)
+ ;; Put the point where to check for org-protected
+ (unless (or (get-text-property (match-beginning 2) 'org-protected)
+ (org-at-table-p))
+ (cond ((member (match-string 2) '("\\$" "$"))
+ (if (equal (match-string 2) "\\$")
+ (replace-match (concat (match-string 1) "$"
+ (match-string 3)) t t)
+ (replace-match (concat (match-string 1) "\\$"
+ (match-string 3)) t t)))
+ ((member (match-string 2) '("&" "%" "#"))
+ (if (equal (match-string 1) "\\")
+ (replace-match (match-string 2) t t)
+ (replace-match (concat (match-string 1) "\\"
+ (match-string 2)) t t)))
+ ((equal (match-string 2) "...")
+ (replace-match
+ (concat (match-string 1)
+ (org-export-latex-protect-string "\\ldots{}")) t t))
+ ((equal (match-string 2) "~")
+ (cond ((equal (match-string 1) "\\") nil)
+ ((eq 'org-link (get-text-property 0 'face (match-string 2)))
+ (replace-match (concat (match-string 1) "\\~") t t))
+ (t (replace-match
+ (org-export-latex-protect-string
+ (concat (match-string 1) "\\~{}")) t t))))
+ ((member (match-string 2) '("{" "}"))
+ (unless (save-match-data (org-inside-LaTeX-fragment-p))
+ (if (equal (match-string 1) "\\")
+ (replace-match (match-string 2) t t)
+ (replace-match (concat (match-string 1) "\\"
+ (match-string 2)) t t)))))
+ (unless (save-match-data (org-inside-LaTeX-fragment-p))
+ (cond ((equal (match-string 2) "\\")
+ (replace-match (or (save-match-data
+ (org-export-latex-treat-backslash-char
+ (match-string 1)
+ (match-string 3))) "") t t))
+ ((member (match-string 2) '("_" "^"))
+ (replace-match (or (save-match-data
+ (org-export-latex-treat-sub-super-char
+ sub-superscript
+ (match-string 1)
+ (match-string 2)
+ (match-string 3))) "") t t)))))))
+ '("^\\([^\n$]*?\\|^\\)\\(\\\\?\\$\\)\\([^\n$]*\\)$"
+ "\\([a-za-z0-9]+\\|[ \t\n]\\|\\b\\|\\\\\\)\\(_\\|\\^\\)\\([a-za-z0-9]+\\|[ \t\n]\\|[:punct:]\\|{[a-za-z0-9]+}\\|([a-za-z0-9]+)\\)"
+ "\\(.\\|^\\)\\(\\\\\\)\\([ \t\n]\\|[a-zA-Z&#%{}\"]+\\)"
+ "\\(.\\|^\\)\\(&\\)"
+ "\\(.\\|^\\)\\(#\\)"
+ "\\(.\\|^\\)\\(%\\)"
+ "\\(.\\|^\\)\\({\\)"
+ "\\(.\\|^\\)\\(}\\)"
+ "\\(.\\|^\\)\\(~\\)"
+ "\\(.\\|^\\)\\(\\.\\.\\.\\)"
+ ;; (?\< . "\\textless{}")
+ ;; (?\> . "\\textgreater{}")
+ )))
+
+(defun org-export-latex-treat-sub-super-char
+ (subsup string-before char string-after)
+ "Convert the \"_\" and \"^\" characters to LaTeX.
+SUBSUP corresponds to the ^: option in the #+OPTIONS line.
+Convert CHAR depending on STRING-BEFORE and STRING-AFTER."
+ (cond ((equal string-before "\\")
+ (concat string-before char string-after))
+ ;; this is part of a math formula
+ ((and (string-match "\\S-+" string-before)
+ (string-match "\\S-+" string-after))
+ (cond ((eq 'org-link (get-text-property 0 'face char))
+ (concat string-before "\\" char string-after))
+ ((save-match-data (org-inside-LaTeX-fragment-p))
+ (if subsup
+ (cond ((eq 1 (length string-after))
+ (concat string-before char string-after))
+ ((string-match "[({]?\\([^)}]+\\)[)}]?" string-after)
+ (format "%s%s{%s}" string-before char
+ (match-string 1 string-after))))))
+ ((and subsup
+ (> (length string-after) 1)
+ (string-match "[({]?\\([^)}]+\\)[)}]?" string-after))
+ (format "$%s%s{%s}$" string-before char
+ (match-string 1 string-after)))
+ (subsup (concat "$" string-before char string-after "$"))
+ (t (org-export-latex-protect-string
+ (concat string-before "\\" char "{}" string-after)))))
+ (t (org-export-latex-protect-string
+ (concat string-before "\\" char "{}" string-after)))))
+
+(defun org-export-latex-treat-backslash-char (string-before string-after)
+ "Convert the \"$\" special character to LaTeX.
+The conversion is made depending of STRING-BEFORE and STRING-AFTER."
+ (cond ((member (list string-after) org-html-entities)
+ ;; backslash is part of a special entity (like "\alpha")
+ (concat string-before "$\\"
+ (or (cdar (member (list string-after) org-html-entities))
+ string-after) "$"))
+ ((and (not (string-match "^[ \n\t]" string-after))
+ (not (string-match "[ \t]\\'\\|^" string-before)))
+ ;; backslash is inside a word
+ (org-export-latex-protect-string
+ (concat string-before "\\textbackslash{}" string-after)))
+ ((not (or (equal string-after "")
+ (string-match "^[ \t\n]" string-after)))
+ ;; backslash might escape a character (like \#) or a user TeX
+ ;; macro (like \setcounter)
+ (org-export-latex-protect-string
+ (concat string-before "\\" string-after)))
+ ((and (string-match "^[ \t\n]" string-after)
+ (string-match "[ \t\n]\\'" string-before))
+ ;; backslash is alone, convert it to $\backslash$
+ (org-export-latex-protect-string
+ (concat string-before "\\textbackslash{}" string-after)))
+ (t (org-export-latex-protect-string
+ (concat string-before "\\textbackslash{}" string-after)))))
+
+(defun org-export-latex-keywords (timestamps)
+ "Convert special keywords to LaTeX.
+Regexps are those from `org-export-latex-special-string-regexps'."
+ (let ((rg org-export-latex-special-string-regexps) r)
+ (while (setq r (pop rg))
+ (goto-char (point-min))
+ (while (re-search-forward (eval r) nil t)
+ (if (not timestamps)
+ (replace-match (format "\\\\texttt{%s}" (match-string 0)) t)
+ (replace-match ""))))))
+
+(defun org-export-latex-fixed-width (opt)
+ "When OPT is non-nil convert fixed-width sections to LaTeX."
+ (goto-char (point-min))
+ (while (re-search-forward "^[ \t]*:" nil t)
+ (if opt
+ (progn (goto-char (match-beginning 0))
+ (insert "\\begin{verbatim}\n")
+ (while (looking-at "^\\([ \t]*\\):\\(.*\\)$")
+ (replace-match (concat (match-string 1)
+ (match-string 2)) t t)
+ (forward-line))
+ (insert "\\end{verbatim}\n\n"))
+ (progn (goto-char (match-beginning 0))
+ (while (looking-at "^\\([ \t]*\\):\\(.*\\)$")
+ (replace-match (concat "%" (match-string 1)
+ (match-string 2)) t t)
+ (forward-line))))))
+
+(defun org-export-latex-tables (insert)
+ "Convert tables to LaTeX and INSERT it."
+ (goto-char (point-min))
+ (while (re-search-forward "^\\([ \t]*\\)|" nil t)
+ ;; FIXME really need to save-excursion?
+ (save-excursion (org-table-align))
+ (let* ((beg (org-table-begin))
+ (end (org-table-end))
+ (raw-table (buffer-substring-no-properties beg end))
+ fnum fields line lines olines gr colgropen line-fmt align)
+ (if org-export-latex-tables-verbatim
+ (let* ((tbl (concat "\\begin{verbatim}\n" raw-table
+ "\\end{verbatim}\n")))
+ (apply 'delete-region (list beg end))
+ (insert tbl))
+ (progn
+ (setq lines (split-string raw-table "\n" t))
+ (apply 'delete-region (list beg end))
+ (when org-export-table-remove-special-lines
+ (setq lines (org-table-clean-before-export lines)))
+ ;; make a formatting string to reflect aligment
+ (setq olines lines)
+ (while (and (not line-fmt) (setq line (pop olines)))
+ (unless (string-match "^[ \t]*|-" line)
+ (setq fields (org-split-string line "[ \t]*|[ \t]*"))
+ (setq fnum (make-vector (length fields) 0))
+ (setq line-fmt
+ (mapconcat
+ (lambda (x)
+ (setq gr (pop org-table-colgroup-info))
+ (format "%s%%s%s"
+ (cond ((eq gr ':start)
+ (prog1 (if colgropen "|" "")
+ (setq colgropen t)))
+ ((eq gr ':startend)
+ (prog1 (if colgropen "|" "|")
+ (setq colgropen nil)))
+ (t ""))
+ (if (memq gr '(:end :startend))
+ (progn (setq colgropen nil) "|")
+ "")))
+ fnum ""))))
+ ;; fix double || in line-fmt
+ (setq line-fmt (replace-regexp-in-string "||" "|" line-fmt))
+ ;; maybe remove the first and last "|"
+ (when (and (not org-export-latex-tables-column-borders)
+ (string-match "^\\(|\\)?\\(.+\\)|$" line-fmt))
+ (setq line-fmt (match-string 2 line-fmt)))
+ ;; format alignment
+ (setq align (apply 'format
+ (cons line-fmt
+ (mapcar (lambda (x) (if x "r" "l"))
+ org-table-last-alignment))))
+ ;; prepare the table to send to orgtbl-to-latex
+ (setq lines
+ (mapcar
+ (lambda(elem)
+ (or (and (string-match "[ \t]*|-+" elem) 'hline)
+ (split-string (org-trim elem) "|" t)))
+ lines))
+ (when insert
+ (insert (orgtbl-to-latex
+ lines `(:tstart ,(concat "\\begin{tabular}{" align "}")))
+ "\n\n")))))))
+
+(defun org-export-latex-fontify ()
+ "Convert fontification to LaTeX."
+ (goto-char (point-min))
+ (while (re-search-forward org-emph-re nil t)
+ ;; The match goes one char after the *string*
+ (let ((emph (assoc (match-string 3)
+ org-export-latex-emphasis-alist))
+ rpl)
+ (unless (get-text-property (1- (point)) 'org-protected)
+ (setq rpl (concat (match-string 1)
+ (format (org-export-latex-protect-char-in-string
+ '("\\" "{" "}") (cadr emph))
+ (match-string 4))
+ (match-string 5)))
+ (if (caddr emph)
+ (setq rpl (org-export-latex-protect-string rpl)))
+ (replace-match rpl t t)))
+ (backward-char)))
+
+(defun org-export-latex-links ()
+ ;; Make sure to use the LaTeX hyperref and graphicx package
+ ;; or send some warnings.
+ "Convert links to LaTeX."
+ (goto-char (point-min))
+ (while (re-search-forward org-bracket-link-analytic-regexp nil t)
+ (org-if-unprotected
+ (goto-char (match-beginning 0))
+ (let* ((re-radio org-export-latex-all-targets-re)
+ (remove (list (match-beginning 0) (match-end 0)))
+ (type (match-string 2))
+ (raw-path (match-string 3))
+ (full-raw-path (concat (match-string 1) raw-path))
+ (desc (match-string 5))
+ imgp radiop
+ ;; define the path of the link
+ (path (cond
+ ((member type '("http" "https" "ftp"))
+ (concat type ":" raw-path))
+ ((and re-radio (string-match re-radio raw-path))
+ (setq radiop t))
+ ((equal type "mailto")
+ (concat type ":" raw-path))
+ ((equal type "file")
+ (if (and (or (org-file-image-p (expand-file-name raw-path))
+ (string-match "\\.eps$" raw-path))
+ (equal desc full-raw-path))
+ (setq imgp t)
+ (progn (when (string-match "\\(.+\\)::.+" raw-path)
+ (setq raw-path (match-string 1 raw-path)))
+ (if (file-exists-p raw-path)
+ (concat type "://" (expand-file-name raw-path))
+ (concat type "://" (org-export-directory
+ :LaTeX org-export-latex-options-plist)
+ raw-path))))))))
+ ;; process with link inserting
+ (apply 'delete-region remove)
+ (cond ((and imgp (plist-get org-export-latex-options-plist :inline-images))
+ (insert (format "\\includegraphics[%s]{%s}"
+ ;; image option should be set be a comment line
+ org-export-latex-image-default-option
+ (expand-file-name raw-path))))
+ (radiop (insert (format "\\hyperref[%s]{%s}" raw-path desc)))
+ (path (insert (format "\\href{%s}{%s}" path desc)))
+ (t (insert "\\texttt{" desc "}")))))))
+
+(defvar org-latex-entities) ; defined below
+
+(defun org-export-latex-cleaned-string ()
+ "Clean stuff in the LaTeX export."
+
+ ;; Preserve line breaks
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\\\\\" nil t)
+ (add-text-properties (match-beginning 0) (match-end 0)
+ '(org-protected t)))
+
+ ;; Convert LaTeX to \LaTeX{}
+ (goto-char (point-min))
+ (let ((case-fold-search nil) rpl)
+ (while (re-search-forward "\\([^+_]\\)LaTeX" nil t)
+ (replace-match (org-export-latex-protect-string
+ (concat (match-string 1) "\\LaTeX{}")) t t)))
+
+ ;; Convert horizontal rules
+ (goto-char (point-min))
+ (while (re-search-forward "^----+.$" nil t)
+ (replace-match (org-export-latex-protect-string "\\hrule") t t))
+
+ ;; Protect LaTeX commands like \commad[...]{...} or \command{...}
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\[a-zA-Z]+\\(?:\\[.*\\]\\)?{.*}" nil t)
+ (add-text-properties (match-beginning 0) (match-end 0)
+ '(org-protected t)))
+
+ ;; Protect LaTeX entities
+ (goto-char (point-min))
+ (while (re-search-forward (regexp-opt org-latex-entities) nil t)
+ (add-text-properties (match-beginning 0) (match-end 0)
+ '(org-protected t)))
+
+ ;; Replace radio links
+ (goto-char (point-min))
+ (while (re-search-forward
+ (concat "<<<?" org-export-latex-all-targets-re
+ ">>>?\\((INVISIBLE)\\)?") nil t)
+ (replace-match
+ (org-export-latex-protect-string
+ (format "\\label{%s}%s"(match-string 1)
+ (if (match-string 2) "" (match-string 1)))) t t))
+
+ ;; Delete @<...> constructs
+ ;; Thanks to Daniel Clemente for this regexp
+ (goto-char (point-min))
+ (while (re-search-forward "@<\\(?:[^\"\n]\\|\".*\"\\)*?>" nil t)
+ (replace-match ""))
+
+ ;; When converting to LaTeX, replace footnotes
+ ;; FIXME: don't protect footnotes from conversion
+ (when (plist-get org-export-latex-options-plist :footnotes)
+ (goto-char (point-min))
+ (while (re-search-forward "\\[[0-9]+\\]" nil t)
+ (when (save-match-data
+ (save-excursion (beginning-of-line)
+ (looking-at "[^:|#]")))
+ (let ((foot-beg (match-beginning 0))
+ (foot-end (match-end 0))
+ (foot-prefix (match-string 0))
+ footnote footnote-rpl)
+ (save-excursion
+ (when (search-forward foot-prefix nil t)
+ (replace-match "")
+ (let ((end (save-excursion
+ (if (re-search-forward "^$\\|^#.*$\\|\\[[0-9]+\\]" nil t)
+ (match-beginning 0) (point-max)))))
+ (setq footnote (concat (org-trim (buffer-substring (point) end))
+ " ")) ; prevent last } being part of a link
+ (delete-region (point) end))
+ (goto-char foot-beg)
+ (delete-region foot-beg foot-end)
+ (unless (null footnote)
+ (setq footnote-rpl (format "\\footnote{%s}" footnote))
+ (add-text-properties 0 10 '(org-protected t) footnote-rpl)
+ (add-text-properties (1- (length footnote-rpl))
+ (length footnote-rpl)
+ '(org-protected t) footnote-rpl)
+ (insert footnote-rpl)))))))
+
+ ;; Replace footnote section tag for LaTeX
+ (goto-char (point-min))
+ (while (re-search-forward
+ (concat "^" footnote-section-tag-regexp) nil t)
+ (replace-match ""))))
+
+;;; List handling:
+
+(defun org-export-latex-lists ()
+ "Replace plain text lists in current buffer into LaTeX lists."
+ "Convert lists to LaTeX."
+ (goto-char (point-min))
+ (while (re-search-forward org-export-latex-list-beginning-re nil t)
+ (beginning-of-line)
+ (insert (org-list-to-latex (org-list-parse-list t)) "\n")))
+
+(defun org-list-parse-list (&optional delete)
+ "Parse the list at point.
+Return a list containing first level items as strings and
+sublevels as a list of strings."
+ (let ((start (org-list-item-begin))
+ (end (org-list-end))
+ output itemsep)
+ (while (re-search-forward org-export-latex-list-beginning-re end t)
+ (setq itemsep (if (save-match-data
+ (string-match "^[0-9]" (match-string 2)))
+ "[0-9]+\\(?:\\.\\|)\\)" "[-+]"))
+ (let* ((indent1 (match-string 1))
+ (nextitem (save-excursion
+ (save-match-data
+ (or (and (re-search-forward
+ (concat "^" indent1 itemsep " *?") end t)
+ (match-beginning 0)) end))))
+ (item (buffer-substring
+ (point)
+ (or (and (re-search-forward
+ org-export-latex-list-beginning-re end t)
+ (goto-char (match-beginning 0)))
+ (goto-char end))))
+ (nextindent (match-string 1))
+ (item (org-trim item))
+ (item (if (string-match "^\\[.+\\]" item)
+ (replace-match "\\\\texttt{\\&}"
+ t nil item) item)))
+ (push item output)
+ (when (> (length nextindent)
+ (length indent1))
+ (narrow-to-region (point) nextitem)
+ (push (org-list-parse-list) output)
+ (widen))))
+ (when delete (delete-region start end))
+ (setq output (nreverse output))
+ (push (if (string-match "^\\[0" itemsep)
+ 'ordered 'unordered) output)))
+
+(defun org-list-item-begin ()
+ "Find the beginning of the list item and return its position."
+ (save-excursion
+ (if (not (or (looking-at org-export-latex-list-beginning-re)
+ (re-search-backward
+ org-export-latex-list-beginning-re nil t)))
+ (progn (goto-char (point-min)) (point))
+ (match-beginning 0))))
+
+(defun org-list-end ()
+ "Find the end of the list and return its position."
+ (save-excursion
+ (catch 'exit
+ (while (or (looking-at org-export-latex-list-beginning-re)
+ (looking-at "^[ \t]+\\|^$"))
+ (if (eq (point) (point-max))
+ (throw 'exit (point-max)))
+ (forward-line 1))) (point)))
+
+(defun org-list-insert-radio-list ()
+ "Insert a radio list template appropriate for this major mode."
+ (interactive)
+ (let* ((e (assq major-mode org-list-radio-list-templates))
+ (txt (nth 1 e))
+ name pos)
+ (unless e (error "No radio list setup defined for %s" major-mode))
+ (setq name (read-string "List name: "))
+ (while (string-match "%n" txt)
+ (setq txt (replace-match name t t txt)))
+ (or (bolp) (insert "\n"))
+ (setq pos (point))
+ (insert txt)
+ (goto-char pos)))
+
+(defun org-list-send-list (&optional maybe)
+ "Send a tranformed version of this list to the receiver position.
+With argument MAYBE, fail quietly if no transformation is defined for
+this list."
+ (interactive)
+ (catch 'exit
+ (unless (org-at-item-p) (error "Not at a list"))
+ (save-excursion
+ (goto-char (org-list-item-begin))
+ (beginning-of-line 0)
+ (unless (looking-at "#\\+ORGLST: *SEND +\\([a-zA-Z0-9_]+\\) +\\([^ \t\r\n]+\\)\\( +.*\\)?")
+ (if maybe
+ (throw 'exit nil)
+ (error "Don't know how to transform this list"))))
+ (let* ((name (match-string 1))
+ beg
+ (transform (intern (match-string 2)))
+ (txt (buffer-substring-no-properties
+ (org-list-item-begin)
+ (org-list-end)))
+ (list (org-list-parse-list)))
+ (unless (fboundp transform)
+ (error "No such transformation function %s" transform))
+ (setq txt (funcall transform list))
+ ;; Find the insertion place
+ (save-excursion
+ (goto-char (point-min))
+ (unless (re-search-forward
+ (concat "BEGIN RECEIVE ORGLST +" name "\\([ \t]\\|$\\)") nil t)
+ (error "Don't know where to insert translated list"))
+ (goto-char (match-beginning 0))
+ (beginning-of-line 2)
+ (setq beg (point))
+ (unless (re-search-forward (concat "END RECEIVE ORGLST +" name) nil t)
+ (error "Cannot find end of insertion region"))
+ (beginning-of-line 1)
+ (delete-region beg (point))
+ (goto-char beg)
+ (insert txt "\n"))
+ (message "List converted and installed at receiver location"))))
+
+(defun org-list-to-generic (list params)
+ "Convert a LIST parsed through `org-list-parse-list' to other formats.
+
+Valid parameters are
+
+:ustart String to start an unordered list
+:uend String to end an unordered list
+
+:ostart String to start an ordered list
+:oend String to end an ordered list
+
+:splice When set to t, return only list body lines, don't wrap
+ them into :[u/o]start and :[u/o]end. Default is nil.
+
+:istart String to start a list item
+:iend String to end a list item
+:isep String to separate items
+:lsep String to separate sublists"
+ (interactive)
+ (let* ((p params) sublist
+ (splicep (plist-get p :splice))
+ (ostart (plist-get p :ostart))
+ (oend (plist-get p :oend))
+ (ustart (plist-get p :ustart))
+ (uend (plist-get p :uend))
+ (istart (plist-get p :istart))
+ (iend (plist-get p :iend))
+ (isep (plist-get p :isep))
+ (lsep (plist-get p :lsep)))
+ (let ((wrapper
+ (cond ((eq (car list) 'ordered)
+ (concat ostart "\n%s" oend "\n"))
+ ((eq (car list) 'unordered)
+ (concat ustart "\n%s" uend "\n"))))
+ rtn)
+ (while (setq sublist (pop list))
+ (cond ((symbolp sublist) nil)
+ ((stringp sublist)
+ (setq rtn (concat rtn istart sublist iend isep)))
+ (t
+ (setq rtn (concat rtn ;; previous list
+ lsep ;; list separator
+ (org-list-to-generic sublist p)
+ lsep ;; list separator
+ )))))
+ (format wrapper rtn))))
+
+(defun org-list-to-latex (list)
+ "Convert LIST into a LaTeX list."
+ (org-list-to-generic
+ list '(:splicep nil :ostart "\\begin{enumerate}" :oend "\\end{enumerate}"
+ :ustart "\\begin{itemize}" :uend "\\end{itemize}"
+ :istart "\\item " :iend ""
+ :isep "\n" :lsep "\n")))
+
+(defun org-list-to-html (list)
+ "Convert LIST into a HTML list."
+ (org-list-to-generic
+ list '(:splicep nil :ostart "<ol>" :oend "</ol>"
+ :ustart "<ul>" :uend "</ul>"
+ :istart "<li>" :iend "</li>"
+ :isep "\n" :lsep "\n")))
+
+(defun org-list-to-texinfo (list)
+ "Convert LIST into a Texinfo list."
+ (org-list-to-generic
+ list '(:splicep nil :ostart "@itemize @minus" :oend "@end itemize"
+ :ustart "@enumerate" :uend "@end enumerate"
+ :istart "@item\n" :iend ""
+ :isep "\n" :lsep "\n")))
+
+(defconst org-latex-entities
+ '("\\!"
+ "\\'"
+ "\\+"
+ "\\,"
+ "\\-"
+ "\\:"
+ "\\;"
+ "\\<"
+ "\\="
+ "\\>"
+ "\\Huge"
+ "\\LARGE"
+ "\\Large"
+ "\\Styles"
+ "\\\\"
+ "\\`"
+ "\\addcontentsline"
+ "\\address"
+ "\\addtocontents"
+ "\\addtocounter"
+ "\\addtolength"
+ "\\addvspace"
+ "\\alph"
+ "\\appendix"
+ "\\arabic"
+ "\\author"
+ "\\begin{array}"
+ "\\begin{center}"
+ "\\begin{description}"
+ "\\begin{enumerate}"
+ "\\begin{eqnarray}"
+ "\\begin{equation}"
+ "\\begin{figure}"
+ "\\begin{flushleft}"
+ "\\begin{flushright}"
+ "\\begin{itemize}"
+ "\\begin{list}"
+ "\\begin{minipage}"
+ "\\begin{picture}"
+ "\\begin{quotation}"
+ "\\begin{quote}"
+ "\\begin{tabbing}"
+ "\\begin{table}"
+ "\\begin{tabular}"
+ "\\begin{thebibliography}"
+ "\\begin{theorem}"
+ "\\begin{titlepage}"
+ "\\begin{verbatim}"
+ "\\begin{verse}"
+ "\\bf"
+ "\\bf"
+ "\\bibitem"
+ "\\bigskip"
+ "\\cdots"
+ "\\centering"
+ "\\circle"
+ "\\cite"
+ "\\cleardoublepage"
+ "\\clearpage"
+ "\\cline"
+ "\\closing"
+ "\\dashbox"
+ "\\date"
+ "\\ddots"
+ "\\dotfill"
+ "\\em"
+ "\\fbox"
+ "\\flushbottom"
+ "\\fnsymbol"
+ "\\footnote"
+ "\\footnotemark"
+ "\\footnotesize"
+ "\\footnotetext"
+ "\\frac"
+ "\\frame"
+ "\\framebox"
+ "\\hfill"
+ "\\hline"
+ "\\hrulespace"
+ "\\hspace"
+ "\\huge"
+ "\\hyphenation"
+ "\\include"
+ "\\includeonly"
+ "\\indent"
+ "\\input"
+ "\\it"
+ "\\kill"
+ "\\label"
+ "\\large"
+ "\\ldots"
+ "\\line"
+ "\\linebreak"
+ "\\linethickness"
+ "\\listoffigures"
+ "\\listoftables"
+ "\\location"
+ "\\makebox"
+ "\\maketitle"
+ "\\mark"
+ "\\mbox"
+ "\\medskip"
+ "\\multicolumn"
+ "\\multiput"
+ "\\newcommand"
+ "\\newcounter"
+ "\\newenvironment"
+ "\\newfont"
+ "\\newlength"
+ "\\newline"
+ "\\newpage"
+ "\\newsavebox"
+ "\\newtheorem"
+ "\\nocite"
+ "\\nofiles"
+ "\\noindent"
+ "\\nolinebreak"
+ "\\nopagebreak"
+ "\\normalsize"
+ "\\onecolumn"
+ "\\opening"
+ "\\oval"
+ "\\overbrace"
+ "\\overline"
+ "\\pagebreak"
+ "\\pagenumbering"
+ "\\pageref"
+ "\\pagestyle"
+ "\\par"
+ "\\parbox"
+ "\\put"
+ "\\raggedbottom"
+ "\\raggedleft"
+ "\\raggedright"
+ "\\raisebox"
+ "\\ref"
+ "\\rm"
+ "\\roman"
+ "\\rule"
+ "\\savebox"
+ "\\sc"
+ "\\scriptsize"
+ "\\setcounter"
+ "\\setlength"
+ "\\settowidth"
+ "\\sf"
+ "\\shortstack"
+ "\\signature"
+ "\\sl"
+ "\\small"
+ "\\smallskip"
+ "\\sqrt"
+ "\\tableofcontents"
+ "\\telephone"
+ "\\thanks"
+ "\\thispagestyle"
+ "\\tiny"
+ "\\title"
+ "\\tt"
+ "\\twocolumn"
+ "\\typein"
+ "\\typeout"
+ "\\underbrace"
+ "\\underline"
+ "\\usebox"
+ "\\usecounter"
+ "\\value"
+ "\\vdots"
+ "\\vector"
+ "\\verb"
+ "\\vfill"
+ "\\vline"
+ "\\vspace")
+ "A list of LaTeX commands to be protected when performing conversion.")
+
+(provide 'org-export-latex)
+
+;; arch-tag: 23c2b87d-da04-4c2d-ad2d-1eb6487bc3ad
+;;; org-export-latex.el ends here
--- /dev/null
+;;; org-irc.el --- Store links to IRC sessions
+
+;; Copyright (C) 2008 Free Software Foundation, Inc.
+
+;; Author: Philip Jackson <emacs@shellarchive.co.uk>
+;; Keywords: erc, irc, link, org
+;; Version: 1.3
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Link to an IRC session. Only ERC has been implemented at the
+;; moment.
+;;
+;; This file is loaded by default whenever org.el is loaded. Please
+;; customize the variable `org-default-extensions' to select extensions
+;; you would like to use, and to deselect those which you don't want.
+;;
+;; Please note that at the moment only ERC is supported. Other clients
+;; shouldn't be diffficult to add though.
+;;
+;; Then set `org-irc-link-to-logs' to non-nil if you would like a
+;; file:/ type link to be created to the current line in the logs or
+;; to t if you would like to create an irc:/ style link.
+;;
+;; Links within an org buffer might look like this:
+;;
+;; [[irc:/irc.freenode.net/#emacs/bob][chat with bob in #emacs on freenode]]
+;; [[irc:/irc.freenode.net/#emacs][#emacs on freenode]]
+;; [[irc:/irc.freenode.net/]]
+;;
+;; If, when the resulting link is visited, there is no connection to a
+;; requested server then one will be created.
+
+;;; Code:
+
+(require 'org)
+(require 'erc)
+(require 'erc-log)
+
+(defvar org-irc-client 'erc
+ "The IRC client to act on")
+(defvar org-irc-link-to-logs nil
+ "non-nil will store a link to the logs, nil will store an irc: style link")
+
+(defvar erc-default-port) ; dynamically scoped from erc.el
+(defvar erc-session-port) ; dynamically scoped form erc-backend.el
+(defvar erc-server-announced-name) ; dynamically scoped form erc-backend.el
+
+;; Generic functions/config (extend these for other clients)
+
+(add-to-list 'org-store-link-functions
+ 'org-irc-store-link)
+
+(org-add-link-type "irc" 'org-irc-visit nil)
+
+(defun org-irc-visit (link)
+ "Dispatch to the correct visit function based on the client"
+ (let ((link (org-irc-parse-link link)))
+ (cond
+ ((eq org-irc-client 'erc)
+ (org-irc-visit-erc link))
+ (t
+ (error "erc only known client")))))
+
+(defun org-irc-parse-link (link)
+ "Get a of irc link attributes where `link' looks like
+server:port/chan/user (port, chan and user being optional)."
+ (let* ((parts (split-string link "/" t))
+ (len (length parts)))
+ (when (or (< len 1) (> len 3))
+ (error "Failed to parse link needed 1-3 parts, got %d." len))
+ (setcar parts (split-string (car parts) ":" t))
+ parts))
+
+;;;###autoload
+(defun org-irc-store-link ()
+ "Dispatch to the appropreate function to store a link to
+something IRC related"
+ (cond
+ ((eq major-mode 'erc-mode)
+ (org-irc-erc-store-link))))
+
+(defun org-irc-elipsify-description (string &optional after)
+ "Strip starting and ending whitespace and replace any chars
+that appear after the value in `after' with '...'"
+ (let* ((after (number-to-string (or after 30)))
+ (replace-map (list (cons "^[ \t]*" "")
+ (cons "[ \t]*$" "")
+ (cons (concat "^\\(.\\{" after
+ "\\}\\).*") "\\1..."))))
+ (mapc (lambda (x)
+ (when (string-match (car x) string)
+ (setq string (replace-match (cdr x) nil nil string))))
+ replace-map)
+ string))
+
+;; ERC specific functions
+
+(defun org-irc-erc-get-line-from-log (erc-line)
+ "Find the most suitable line to link to from the erc logs. If
+the user is on the erc-prompt then search backward for the first
+non-blank line, otherwise return the current line. The result is
+a cons of the filename and search string."
+ (erc-save-buffer-in-logs)
+ (with-current-buffer (find-file-noselect (erc-current-logfile))
+ (goto-char (point-max))
+ (list
+ (abbreviate-file-name buffer-file-name)
+ ;; can we get a '::' part?
+ (if (string= erc-line (erc-prompt))
+ (progn
+ (goto-char (point-at-bol))
+ (when (search-backward-regexp "^[^ ]" nil t)
+ (buffer-substring-no-properties (point-at-bol)
+ (point-at-eol))))
+ (when (search-backward erc-line nil t)
+ (buffer-substring-no-properties (point-at-bol)
+ (point-at-eol)))))))
+
+(defun org-irc-erc-store-link ()
+ "Depending on the variable `org-irc-link-to-logs' store either
+a link to the log file for the current session or an irc: link to
+the session itself."
+ (if org-irc-link-to-logs
+ (let* ((erc-line (buffer-substring-no-properties
+ (point-at-bol) (point-at-eol)))
+ (parsed-line (org-irc-erc-get-line-from-log erc-line)))
+ (if (erc-logging-enabled nil)
+ (progn
+ (org-store-link-props
+ :type "file"
+ :description (concat "'" (org-irc-elipsify-description
+ (cadr parsed-line) 20)
+ "' from an IRC conversation")
+ :link (concat "file:" (car parsed-line) "::"
+ (cadr parsed-line)))
+ t)
+ (error "This ERC session is not being logged")))
+ (let* ((link-text (org-irc-get-erc-link))
+ (link (org-irc-parse-link link-text)))
+ (if link-text
+ (progn
+ (org-store-link-props
+ :type "irc"
+ :link (org-make-link "irc:/" link-text)
+ :description (concat "irc session '" link-text "'")
+ :server (car (car link))
+ :port (or (cadr (pop link)) erc-default-port)
+ :nick (pop link))
+ t)
+ (error "Failed to create ('irc:/' style) ERC link")))))
+
+(defun org-irc-get-erc-link ()
+ "Return an org compatible irc:/ link from an ERC buffer"
+ (let ((link (concat erc-server-announced-name ":"
+ (number-to-string erc-session-port))))
+ (concat link "/"
+ (if (and (erc-default-target)
+ (erc-channel-p (erc-default-target))
+ (car (get-text-property (point) 'erc-data)))
+ ;; we can get a nick
+ (let ((nick (car (get-text-property (point) 'erc-data))))
+ (concat (erc-default-target) "/" nick))
+ (erc-default-target)))))
+
+(defun org-irc-visit-erc (link)
+ "Visit an ERC buffer based on criteria from the followed link"
+ (let* ((server (car (car link)))
+ (port (or (cadr (pop link)) erc-default-port))
+ (server-buffer)
+ (buffer-list
+ (erc-buffer-filter
+ (lambda nil
+ (let ((tmp-server-buf (erc-server-buffer)))
+ (and tmp-server-buf
+ (with-current-buffer tmp-server-buf
+ (and
+ (string= erc-session-port port)
+ (string= erc-server-announced-name server)
+ (setq server-buffer tmp-server-buf)))))))))
+ (if buffer-list
+ (let ((chan-name (pop link)))
+ ;; if we got a channel name then switch to it or join it
+ (if chan-name
+ (let ((chan-buf (catch 'found
+ (dolist (x buffer-list)
+ (if (string= (buffer-name x) chan-name)
+ (throw 'found x))))))
+ (if chan-buf
+ (progn
+ (switch-to-buffer chan-buf)
+ ;; if we got a nick, and they're in the chan,
+ ;; then start a chat with them
+ (let ((nick (pop link)))
+ (when nick
+ (if (member nick (erc-get-server-nickname-list))
+ (progn
+ (goto-char (point-max))
+ (insert (concat nick ": ")))
+ (error "%s not found in %s" nick chan-name)))))
+ (progn
+ (switch-to-buffer server-buffer)
+ (erc-cmd-JOIN chan-name))))
+ (switch-to-buffer server-buffer)))
+ ;; no server match, make new connection
+ (erc-select :server server :port port))))
+
+(provide 'org-irc)
+
+;; arch-tag: 018d7dda-53b8-4a35-ba92-6670939e525a
+;;; org-irc.el ends here
--- /dev/null
+;;; org-mac-message.el --- Support for links to Apple Mail messages by Message-ID
+
+;; Copyright (C) 2008 Free Software Foundation, Inc.
+
+;; Author: John Wiegley <johnw@gnu.org>
+;; Version: 1.2
+;; Keywords: outlines, hypermedia, calendar, wp
+
+;; This file is part of GNU Emacs.
+
+;; Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Code:
+
+(require 'org)
+
+(org-add-link-type "message" 'org-mac-message-open)
+
+(unless (fboundp 'do-applescript)
+ ;; Need to fake this using shell-command-to-string
+ (defun do-applescript (script)
+ (let (start cmd return)
+ (while (string-match "\n" script)
+ (setq script (replace-match "\r" t t script)))
+ (while (string-match "'" script start)
+ (setq start (+ 2 (match-beginning 0))
+ script (replace-match "\\'" t t script)))
+ (setq cmd (concat "osascript -e '" script "'"))
+ (setq return (shell-command-to-string cmd))
+ (concat "\"" (org-trim return) "\""))))
+
+(defun org-mac-message-open (message-id)
+ "Visit the message with the given Message-ID.
+This will use the command `open' with the message url."
+ (start-process (concat "open message:" message-id) nil
+ "open" (concat "message://<" (substring message-id 2) ">")))
+
+(defun org-mac-message-insert-link ()
+ "Insert a link to the messages currently selected in Apple Mail.
+This will use applescript to get the message-id and the subject of the
+active mail in AppleMail and make a link out of it."
+ (interactive)
+ (insert (org-mac-message-get-link)))
+
+(defun org-mac-message-get-link ()
+ "Insert a link to the messages currently selected in Apple Mail.
+This will use applescript to get the message-id and the subject of the
+active mail in AppleMail and make a link out of it."
+ (let ((subject (do-applescript "tell application \"Mail\"
+ set theMessages to selection
+ subject of beginning of theMessages
+end tell"))
+ (message-id (do-applescript "tell application \"Mail\"
+ set theMessages to selection
+ message id of beginning of theMessages
+end tell")))
+ (org-make-link-string
+ (concat "message://"
+ (substring message-id 1 (1- (length message-id))))
+ (substring subject 1 (1- (length subject))))))
+
+(provide 'org-mac-message)
+
+;; arch-tag: 3806d0c1-abe1-4db6-9c31-f3ed7d4a9b32
+;;; org-mac-message.el ends here
--- /dev/null
+;;; org-mouse.el --- Better mouse support for org-mode
+
+;; Copyright (C) 2006, 2007, 2008 Free Software Foundation
+;;
+;; Author: Piotr Zielinski <piotr dot zielinski at gmail dot com>
+;; Maintainer: Carsten Dominik <carsten at orgmode dot org>
+;; Version: 5.23
+;;
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;; Org-mouse provides mouse support for org-mode.
+;;
+;; http://orgmode.org
+;;
+;; Org-mouse implements the following features:
+;; * following links with the left mouse button (in Emacs 22)
+;; * subtree expansion/collapse (org-cycle) with the left mouse button
+;; * several context menus on the right mouse button:
+;; + general text
+;; + headlines
+;; + timestamps
+;; + priorities
+;; + links
+;; + tags
+;; * promoting/demoting/moving subtrees with mouse-3
+;; + if the drag starts and ends in the same line then promote/demote
+;; + otherwise move the subtree
+;;
+;; Use
+;; ---
+;;
+;; To use this package, put the following line in your .emacs:
+;;
+;; (require 'org-mouse)
+;;
+
+;; Fixme:
+;; + deal with folding / unfolding issues
+
+;; TODO (This list is only theoretical, if you'd like to have some
+;; feature implemented or a bug fix please send me an email, even if
+;; something similar appears in the list below. This will help me get
+;; the priorities right.):
+;;
+;; + org-store-link, insert link
+;; + org tables
+;; + occur with the current word/tag (same menu item)
+;; + ctrl-c ctrl-c, for example, renumber the current list
+;; + internal links
+
+;; Please email the maintainer with new feature suggestions / bugs
+
+;; History:
+;;
+;; SInce version 5.10: Changes are listed in the general org-mode docs.
+;;
+;; Version 5.09
+;; + Version number synchronization with Org-mode.
+;;
+;; Version 0.25
+;; + made compatible with org-mode 4.70 (thanks to Carsten for the patch)
+;;
+;; Version 0.24
+;; + minor changes to the table menu
+;;
+;; Version 0.23
+;; + preliminary support for tables and calculation marks
+;; + context menu support for org-agenda-undo & org-sort-entries
+;;
+;; Version 0.22
+;; + handles undo support for the agenda buffer (requires org-mode >=4.58)
+;;
+;; Version 0.21
+;; + selected text activates its context menu
+;; + shift-middleclick or right-drag inserts the text from the clipboard in the form of a link
+;;
+;; Version 0.20
+;; + the new "TODO Status" submenu replaces the "Cycle TODO" menu item
+;; + the TODO menu can now list occurrences of a specific TODO keyword
+;; + #+STARTUP line is now recognized
+;;
+;; Version 0.19
+;; + added support for dragging URLs to the org-buffer
+;;
+;; Version 0.18
+;; + added support for agenda blocks
+;;
+;; Version 0.17
+;; + toggle checkboxes with a single click
+;;
+;; Version 0.16
+;; + added support for checkboxes
+;;
+;; Version 0.15
+;; + org-mode now works with the Agenda buffer as well
+;;
+;; Version 0.14
+;; + added a menu option that converts plain list items to outline items
+;;
+;; Version 0.13
+;; + "Insert Heading" now inserts a sibling heading if the point is
+;; on "***" and a child heading otherwise
+;;
+;; Version 0.12
+;; + compatible with Emacs 21
+;; + custom agenda commands added to the main menu
+;; + moving trees should now work between windows in the same frame
+;;
+;; Version 0.11
+;; + fixed org-mouse-at-link (thanks to Carsten)
+;; + removed [follow-link] bindings
+;;
+;; Version 0.10
+;; + added a menu option to remove highlights
+;; + compatible with org-mode 4.21 now
+;;
+;; Version 0.08:
+;; + trees can be moved/promoted/demoted by dragging with the right
+;; mouse button (mouse-3)
+;; + small changes in the above function
+;;
+;; Versions 0.01 -- 0.07: (I don't remember)
+
+(eval-when-compile (require 'cl))
+(require 'org)
+
+(defvar org-mouse-plain-list-regexp "\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) "
+ "Regular expression that matches a plain list.")
+(defvar org-mouse-direct t
+ "Internal variable indicating whether the current action is direct.
+
+If t, then the current action has been invoked directly through the buffer
+it is intended to operate on. If nil, then the action has been invoked
+indirectly, for example, through the agenda buffer.")
+
+(defgroup org-mouse nil
+ "Mouse support for org-mode."
+ :tag "Org Mouse"
+ :group 'org)
+
+(defcustom org-mouse-punctuation ":"
+ "Punctuation used when inserting text by drag and drop."
+ :group 'org-mouse
+ :type 'string)
+
+
+(defun org-mouse-re-search-line (regexp)
+ "Search the current line for a given regular expression."
+ (beginning-of-line)
+ (re-search-forward regexp (point-at-eol) t))
+
+(defun org-mouse-end-headline ()
+ "Go to the end of current headline (ignoring tags)."
+ (interactive)
+ (end-of-line)
+ (skip-chars-backward "\t ")
+ (when (looking-back ":[A-Za-z]+:")
+ (skip-chars-backward ":A-Za-z")
+ (skip-chars-backward "\t ")))
+
+(defvar org-mouse-context-menu-function nil
+ "Function to create the context menu.
+The value of this variable is the function invoked by
+`org-mouse-context-menu' as the context menu.")
+(make-variable-buffer-local 'org-mouse-context-menu-function)
+
+(defun org-mouse-show-context-menu (event prefix)
+ "Invoke the context menu.
+
+If the value of `org-mouse-context-menu-function' is a function, then
+this function is called. Otherwise, the current major mode menu is used."
+ (interactive "@e \nP")
+ (if (and (= (event-click-count event) 1)
+ (or (not mark-active)
+ (sit-for (/ double-click-time 1000.0))))
+ (progn
+ (select-window (posn-window (event-start event)))
+ (when (not (org-mouse-mark-active))
+ (goto-char (posn-point (event-start event)))
+ (when (not (eolp)) (save-excursion (run-hooks 'post-command-hook)))
+ (let ((redisplay-dont-pause t))
+ (sit-for 0)))
+ (if (functionp org-mouse-context-menu-function)
+ (funcall org-mouse-context-menu-function event)
+ (mouse-major-mode-menu event prefix)))
+ (setq this-command 'mouse-save-then-kill)
+ (mouse-save-then-kill event)))
+
+
+(defun org-mouse-line-position ()
+ "Returns `:beginning' or `:middle' or `:end', depending on the point position.
+
+If the point is at the end of the line, return `:end'.
+If the point is separated from the beginning of the line only by white
+space and *'s (`org-mouse-bolp'), return `:beginning'. Otherwise,
+return `:middle'."
+ (cond
+ ((eolp) :end)
+ ((org-mouse-bolp) :beginning)
+ (t :middle)))
+
+(defun org-mouse-empty-line ()
+ "Return non-nil iff the line contains only white space."
+ (save-excursion (beginning-of-line) (looking-at "[ \t]*$")))
+
+(defun org-mouse-next-heading ()
+ "Go to the next heading.
+If there is none, ensure that the point is at the beginning of an empty line."
+ (unless (outline-next-heading)
+ (beginning-of-line)
+ (unless (org-mouse-empty-line)
+ (end-of-line)
+ (newline))))
+
+(defun org-mouse-insert-heading ()
+ "Insert a new heading, as `org-insert-heading'.
+
+If the point is at the :beginning (`org-mouse-line-position') of the line,
+insert the new heading before the current line. Otherwise, insert it
+after the current heading."
+ (interactive)
+ (case (org-mouse-line-position)
+ (:beginning (beginning-of-line)
+ (org-insert-heading))
+ (t (org-mouse-next-heading)
+ (org-insert-heading))))
+
+(defun org-mouse-timestamp-today (&optional shift units)
+ "Change the timestamp into SHIFT UNITS in the future.
+
+For the acceptable UNITS, see `org-timestamp-change'."
+ (interactive)
+ (flet ((org-read-date (&rest rest) (current-time)))
+ (org-time-stamp nil))
+ (when shift
+ (org-timestamp-change shift units)))
+
+(defun org-mouse-keyword-menu (keywords function &optional selected itemformat)
+ "A helper function.
+
+Returns a menu fragment consisting of KEYWORDS. When a keyword
+is selected by the user, FUNCTION is called with the selected
+keyword as the only argument.
+
+If SELECTED is nil, then all items are normal menu items. If
+SELECTED is a function, then each item is a checkbox, which is
+enabled for a given keyword iff (funcall SELECTED keyword) return
+non-nil. If SELECTED is neither nil nor a function, then the
+items are radio buttons. A radio button is enabled for the
+keyword `equal' to SELECTED.
+
+ITEMFORMAT governs formatting of the elements of KEYWORDS. If it
+is a function, it is invoked with the keyword as the only
+argument. If it is a string, it is interpreted as the format
+string to (format ITEMFORMAT keyword). If it is neither a string
+nor a function, elements of KEYWORDS are used directly. "
+ (mapcar
+ `(lambda (keyword)
+ (vector (cond
+ ((functionp ,itemformat) (funcall ,itemformat keyword))
+ ((stringp ,itemformat) (format ,itemformat keyword))
+ (t keyword))
+ (list 'funcall ,function keyword)
+ :style (cond
+ ((null ,selected) t)
+ ((functionp ,selected) 'toggle)
+ (t 'radio))
+ :selected (if (functionp ,selected)
+ (and (funcall ,selected keyword) t)
+ (equal ,selected keyword))))
+ keywords))
+
+(defun org-mouse-remove-match-and-spaces ()
+ "Remove the match, make just one space around the point."
+ (interactive)
+ (replace-match "")
+ (just-one-space))
+
+(defvar rest)
+(defun org-mouse-replace-match-and-surround (newtext &optional fixedcase
+ literal string subexp)
+ "The same as `replace-match', but surrounds the replacement with spaces."
+ (apply 'replace-match rest)
+ (save-excursion
+ (goto-char (match-beginning (or subexp 0)))
+ (just-one-space)
+ (goto-char (match-end (or subexp 0)))
+ (just-one-space)))
+
+
+(defun org-mouse-keyword-replace-menu (keywords &optional group itemformat
+ nosurround)
+ "A helper function.
+
+Returns a menu fragment consisting of KEYWORDS. When a keyword
+is selected, group GROUP of the current match is replaced by the
+keyword. The method ensures that both ends of the replacement
+are separated from the rest of the text in the buffer by
+individual spaces (unless NOSURROND is non-nil).
+
+The final entry of the menu is always \"None\", which removes the
+match.
+
+ITEMFORMAT governs formatting of the elements of KEYWORDS. If it
+is a function, it is invoked with the keyword as the only
+argument. If it is a string, it is interpreted as the format
+string to (format ITEMFORMAT keyword). If it is neither a string
+nor a function, elements of KEYWORDS are used directly.
+"
+ (setq group (or group 0))
+ (let ((replace (org-mouse-match-closure
+ (if nosurround 'replace-match
+ 'org-mouse-replace-match-and-surround))))
+ (append
+ (org-mouse-keyword-menu
+ keywords
+ `(lambda (keyword) (funcall ,replace keyword t t nil ,group))
+ (match-string group)
+ itemformat)
+ `(["None" org-mouse-remove-match-and-spaces
+ :style radio
+ :selected ,(not (member (match-string group) keywords))]))))
+
+(defun org-mouse-show-headlines ()
+ "Change the visibility of the current org buffer to only show headlines."
+ (interactive)
+ (let ((this-command 'org-cycle)
+ (last-command 'org-cycle)
+ (org-cycle-global-status nil))
+ (org-cycle '(4))
+ (org-cycle '(4))))
+
+(defun org-mouse-show-overview ()
+ "Change visibility of current org buffer to first-level headlines only."
+ (interactive)
+ (let ((org-cycle-global-status nil))
+ (org-cycle '(4))))
+
+(defun org-mouse-set-priority (priority)
+ "Set the priority of the current headline to PRIORITY."
+ (flet ((read-char-exclusive () priority))
+ (org-priority)))
+
+(defvar org-mouse-priority-regexp "\\[#\\([A-Z]\\)\\]"
+ "Regular expression matching the priority indicator.
+Differs from `org-priority-regexp' in that it doesn't contain the
+leading '.*?'.")
+
+(defun org-mouse-get-priority (&optional default)
+ "Return the priority of the current headline.
+DEFAULT is returned if no priority is given in the headline."
+ (save-excursion
+ (if (org-mouse-re-search-line org-mouse-priority-regexp)
+ (match-string 1)
+ (when default (char-to-string org-default-priority)))))
+
+;; (defun org-mouse-at-link ()
+;; (and (eq (get-text-property (point) 'face) 'org-link)
+;; (save-excursion
+;; (goto-char (previous-single-property-change (point) 'face))
+;; (or (looking-at org-bracket-link-regexp)
+;; (looking-at org-angle-link-re)
+;; (looking-at org-plain-link-re)))))
+
+
+(defun org-mouse-delete-timestamp ()
+ "Deletes the current timestamp as well as the preceding keyword.
+SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:"
+ (when (or (org-at-date-range-p) (org-at-timestamp-p))
+ (replace-match "") ; delete the timestamp
+ (skip-chars-backward " :A-Z")
+ (when (looking-at " *[A-Z][A-Z]+:")
+ (replace-match ""))))
+
+(defun org-mouse-looking-at (regexp skipchars &optional movechars)
+ (save-excursion
+ (let ((point (point)))
+ (if (looking-at regexp) t
+ (skip-chars-backward skipchars)
+ (forward-char (or movechars 0))
+ (when (looking-at regexp)
+ (> (match-end 0) point))))))
+
+(defun org-mouse-priority-list ()
+ (loop for priority from ?A to org-lowest-priority
+ collect (char-to-string priority)))
+
+(defun org-mouse-tag-menu () ;todo
+ (append
+ (let ((tags (org-split-string (org-get-tags) ":")))
+ (org-mouse-keyword-menu
+ (sort (mapcar 'car (org-get-buffer-tags)) 'string-lessp)
+ `(lambda (tag)
+ (org-mouse-set-tags
+ (sort (if (member tag (quote ,tags))
+ (delete tag (quote ,tags))
+ (cons tag (quote ,tags)))
+ 'string-lessp)))
+ `(lambda (tag) (member tag (quote ,tags)))
+ ))
+ '("--"
+ ["Align Tags Here" (org-set-tags nil t) t]
+ ["Align Tags in Buffer" (org-set-tags t t) t]
+ ["Set Tags ..." (org-set-tags) t])))
+
+
+
+(defun org-mouse-set-tags (tags)
+ (save-excursion
+ ;; remove existing tags first
+ (beginning-of-line)
+ (when (org-mouse-re-search-line ":\\(\\([A-Za-z_]+:\\)+\\)")
+ (replace-match ""))
+
+ ;; set new tags if any
+ (when tags
+ (end-of-line)
+ (insert " :" (mapconcat 'identity tags ":") ":")
+ (org-set-tags nil t))))
+
+(defun org-mouse-insert-checkbox ()
+ (interactive)
+ (and (org-at-item-p)
+ (goto-char (match-end 0))
+ (unless (org-at-item-checkbox-p)
+ (delete-horizontal-space)
+ (insert " [ ] "))))
+
+(defun org-mouse-agenda-type (type)
+ (case type
+ ('tags "Tags: ")
+ ('todo "TODO: ")
+ ('tags-tree "Tags tree: ")
+ ('todo-tree "TODO tree: ")
+ ('occur-tree "Occur tree: ")
+ (t "Agenda command ???")))
+
+
+(defun org-mouse-list-options-menu (alloptions &optional function)
+ (let ((options (save-match-data
+ (split-string (match-string-no-properties 1)))))
+ (print options)
+ (loop for name in alloptions
+ collect
+ (vector name
+ `(progn
+ (replace-match
+ (mapconcat 'identity
+ (sort (if (member ',name ',options)
+ (delete ',name ',options)
+ (cons ',name ',options))
+ 'string-lessp)
+ " ")
+ nil nil nil 1)
+ (when (functionp ',function) (funcall ',function)))
+ :style 'toggle
+ :selected (and (member name options) t)))))
+
+(defun org-mouse-clip-text (text maxlength)
+ (if (> (length text) maxlength)
+ (concat (substring text 0 (- maxlength 3)) "...")
+ text))
+
+(defun org-mouse-popup-global-menu ()
+ (popup-menu
+ `("Main Menu"
+ ["Show Overview" org-mouse-show-overview t]
+ ["Show Headlines" org-mouse-show-headlines t]
+ ["Show All" show-all t]
+ ["Remove Highlights" org-remove-occur-highlights
+ :visible org-occur-highlights]
+ "--"
+ ["Check Deadlines"
+ (if (functionp 'org-check-deadlines-and-todos)
+ (org-check-deadlines-and-todos org-deadline-warning-days)
+ (org-check-deadlines org-deadline-warning-days)) t]
+ ["Check TODOs" org-show-todo-tree t]
+ ("Check Tags"
+ ,@(org-mouse-keyword-menu
+ (sort (mapcar 'car (org-get-buffer-tags)) 'string-lessp)
+ '(lambda (tag) (org-tags-sparse-tree nil tag)))
+ "--"
+ ["Custom Tag ..." org-tags-sparse-tree t])
+ ["Check Phrase ..." org-occur]
+ "--"
+ ["Display Agenda" org-agenda-list t]
+ ["Display Timeline" org-timeline t]
+ ["Display TODO List" org-todo-list t]
+ ("Display Tags"
+ ,@(org-mouse-keyword-menu
+ (sort (mapcar 'car (org-get-buffer-tags)) 'string-lessp)
+ '(lambda (tag) (org-tags-view nil tag)))
+ "--"
+ ["Custom Tag ..." org-tags-view t])
+ ["Display Calendar" org-goto-calendar t]
+ "--"
+ ,@(org-mouse-keyword-menu
+ (mapcar 'car org-agenda-custom-commands)
+ '(lambda (key)
+ (eval `(flet ((read-char-exclusive () (string-to-char ,key)))
+ (org-agenda nil))))
+ nil
+ '(lambda (key)
+ (let ((entry (assoc key org-agenda-custom-commands)))
+ (org-mouse-clip-text
+ (cond
+ ((stringp (nth 1 entry)) (nth 1 entry))
+ ((stringp (nth 2 entry))
+ (concat (org-mouse-agenda-type (nth 1 entry))
+ (nth 2 entry)))
+ (t "Agenda Command '%s'"))
+ 30))))
+ "--"
+ ["Delete Blank Lines" delete-blank-lines
+ :visible (org-mouse-empty-line)]
+ ["Insert Checkbox" org-mouse-insert-checkbox
+ :visible (and (org-at-item-p) (not (org-at-item-checkbox-p)))]
+ ["Insert Checkboxes"
+ (org-mouse-for-each-item 'org-mouse-insert-checkbox)
+ :visible (and (org-at-item-p) (not (org-at-item-checkbox-p)))]
+ ["Plain List to Outline" org-mouse-transform-to-outline
+ :visible (org-at-item-p)])))
+
+
+(defun org-mouse-get-context (contextlist context)
+ (let ((contextdata (assq context contextlist)))
+ (when contextdata
+ (save-excursion
+ (goto-char (second contextdata))
+ (re-search-forward ".*" (third contextdata))))))
+
+(defun org-mouse-for-each-item (function)
+ (save-excursion
+ (ignore-errors
+ (while t (org-previous-item)))
+ (ignore-errors
+ (while t
+ (funcall function)
+ (org-next-item)))))
+
+(defun org-mouse-bolp ()
+ "Returns true if there only spaces, tabs, and '*', between the beginning of line and the point"
+ (save-excursion
+ (skip-chars-backward " \t*") (bolp)))
+
+(defun org-mouse-insert-item (text)
+ (case (org-mouse-line-position)
+ (:beginning ; insert before
+ (beginning-of-line)
+ (looking-at "[ \t]*")
+ (open-line 1)
+ (indent-to (- (match-end 0) (match-beginning 0)))
+ (insert "+ "))
+
+ (:middle ; insert after
+ (end-of-line)
+ (newline t)
+ (indent-relative)
+ (insert "+ "))
+
+ (:end ; insert text here
+ (skip-chars-backward " \t")
+ (kill-region (point) (point-at-eol))
+ (unless (looking-back org-mouse-punctuation)
+ (insert (concat org-mouse-punctuation " ")))))
+
+ (insert text)
+ (beginning-of-line))
+
+(defadvice dnd-insert-text (around org-mouse-dnd-insert-text activate)
+ (if (eq major-mode 'org-mode)
+ (org-mouse-insert-item text)
+ ad-do-it))
+
+(defadvice dnd-open-file (around org-mouse-dnd-open-file activate)
+ (if (eq major-mode 'org-mode)
+ (org-mouse-insert-item uri)
+ ad-do-it))
+
+(defun org-mouse-match-closure (function)
+ (let ((match (match-data t)))
+ `(lambda (&rest rest)
+ (save-match-data
+ (set-match-data ',match)
+ (apply ',function rest)))))
+
+(defun org-mouse-todo-keywords ()
+ (if (boundp 'org-todo-keywords-1) org-todo-keywords-1 org-todo-keywords))
+
+(defun org-mouse-match-todo-keyword ()
+ (save-excursion
+ (org-back-to-heading)
+ (if (looking-at outline-regexp) (goto-char (match-end 0)))
+ (or (looking-at (concat " +" org-todo-regexp " *"))
+ (looking-at " \\( *\\)"))))
+
+(defun org-mouse-yank-link (click)
+ (interactive "e")
+ ;; Give temporary modes such as isearch a chance to turn off.
+ (run-hooks 'mouse-leave-buffer-hook)
+ (mouse-set-point click)
+ (setq mouse-selection-click-count 0)
+ (delete-horizontal-space)
+ (insert-for-yank (concat " [[" (current-kill 0) "]] ")))
+
+(defun org-mouse-context-menu (&optional event)
+ (let ((stamp-prefixes (list org-deadline-string org-scheduled-string))
+ (contextlist (org-context)))
+ (flet ((get-context (context) (org-mouse-get-context contextlist context)))
+ (cond
+ ((org-mouse-mark-active)
+ (let ((region-string (buffer-substring (region-beginning) (region-end))))
+ (popup-menu
+ `(nil
+ ["Sparse Tree" (org-occur ',region-string)]
+ ["Find in Buffer" (occur ',region-string)]
+ ["Grep in Current Dir"
+ (grep (format "grep -rnH -e '%s' *" ',region-string))]
+ ["Grep in Parent Dir"
+ (grep (format "grep -rnH -e '%s' ../*" ',region-string))]
+ "--"
+ ["Convert to Link"
+ (progn (save-excursion (goto-char (region-beginning)) (insert "[["))
+ (save-excursion (goto-char (region-end)) (insert "]]")))]
+ ["Insert Link Here" (org-mouse-yank-link ',event)]))))
+
+ ((save-excursion (beginning-of-line) (looking-at "#\\+STARTUP: \\(.*\\)"))
+ (popup-menu
+ `(nil
+ ,@(org-mouse-list-options-menu (mapcar 'car org-startup-options)
+ 'org-mode-restart))))
+ ((or (eolp)
+ (and (looking-at "\\( \\|\t\\)\\(+:[0-9a-zA-Z_:]+\\)?\\( \\|\t\\)+$")
+ (looking-back " \\|\t")))
+ (org-mouse-popup-global-menu))
+ ((get-context :checkbox)
+ (popup-menu
+ '(nil
+ ["Toggle" org-toggle-checkbox t]
+ ["Remove" org-mouse-remove-match-and-spaces t]
+ ""
+ ["All Clear" (org-mouse-for-each-item
+ (lambda ()
+ (when (save-excursion (org-at-item-checkbox-p))
+ (replace-match "[ ]"))))]
+ ["All Set" (org-mouse-for-each-item
+ (lambda ()
+ (when (save-excursion (org-at-item-checkbox-p))
+ (replace-match "[X]"))))]
+ ["All Toggle" (org-mouse-for-each-item 'org-toggle-checkbox) t]
+ ["All Remove" (org-mouse-for-each-item
+ (lambda ()
+ (when (save-excursion (org-at-item-checkbox-p))
+ (org-mouse-remove-match-and-spaces))))]
+ )))
+ ((and (org-mouse-looking-at "\\b\\w+" "a-zA-Z0-9_")
+ (member (match-string 0) (org-mouse-todo-keywords)))
+ (popup-menu
+ `(nil
+ ,@(org-mouse-keyword-replace-menu (org-mouse-todo-keywords))
+ "--"
+ ["Check TODOs" org-show-todo-tree t]
+ ["List all TODO keywords" org-todo-list t]
+ [,(format "List only %s" (match-string 0))
+ (org-todo-list (match-string 0)) t]
+ )))
+ ((and (org-mouse-looking-at "\\b[A-Z]+:" "A-Z")
+ (member (match-string 0) stamp-prefixes))
+ (popup-menu
+ `(nil
+ ,@(org-mouse-keyword-replace-menu stamp-prefixes)
+ "--"
+ ["Check Deadlines" org-check-deadlines t]
+ )))
+ ((org-mouse-looking-at org-mouse-priority-regexp "[]A-Z#") ; priority
+ (popup-menu `(nil ,@(org-mouse-keyword-replace-menu
+ (org-mouse-priority-list) 1 "Priority %s" t))))
+ ((get-context :link)
+ (popup-menu
+ '(nil
+ ["Open" org-open-at-point t]
+ ["Open in Emacs" (org-open-at-point t) t]
+ "--"
+ ["Copy link" (kill-new (match-string 0))]
+ ["Cut link"
+ (progn
+ (kill-region (match-beginning 0) (match-end 0))
+ (just-one-space))]
+ "--"
+ ["Grep for TODOs"
+ (grep (format "grep -nH -i 'todo\\|fixme' %s*" (match-string 2)))]
+; ["Paste file link" ((insert "file:") (yank))]
+ )))
+ ((org-mouse-looking-at ":\\([A-Za-z0-9_]+\\):" "A-Za-z0-9_" -1) ;tags
+ (popup-menu
+ `(nil
+ [,(format "Display '%s'" (match-string 1))
+ (org-tags-view nil ,(match-string 1))]
+ [,(format "Sparse Tree '%s'" (match-string 1))
+ (org-tags-sparse-tree nil ,(match-string 1))]
+ "--"
+ ,@(org-mouse-tag-menu))))
+ ((org-at-timestamp-p)
+ (popup-menu
+ '(nil
+ ["Show Day" org-open-at-point t]
+ ["Change Timestamp" org-time-stamp t]
+ ["Delete Timestamp" (org-mouse-delete-timestamp) t]
+ ["Compute Time Range" org-evaluate-time-range (org-at-date-range-p)]
+ "--"
+ ["Set for Today" org-mouse-timestamp-today]
+ ["Set for Tomorrow" (org-mouse-timestamp-today 1 'day)]
+ ["Set in 1 Week" (org-mouse-timestamp-today 7 'day)]
+ ["Set in 2 Weeks" (org-mouse-timestamp-today 14 'day)]
+ ["Set in a Month" (org-mouse-timestamp-today 1 'month)]
+ "--"
+ ["+ 1 Day" (org-timestamp-change 1 'day)]
+ ["+ 1 Week" (org-timestamp-change 7 'day)]
+ ["+ 1 Month" (org-timestamp-change 1 'month)]
+ "--"
+ ["- 1 Day" (org-timestamp-change -1 'day)]
+ ["- 1 Week" (org-timestamp-change -7 'day)]
+ ["- 1 Month" (org-timestamp-change -1 'month)])))
+ ((get-context :table-special)
+ (let ((mdata (match-data)))
+ (incf (car mdata) 2)
+ (store-match-data mdata))
+ (message "match: %S" (match-string 0))
+ (popup-menu `(nil ,@(org-mouse-keyword-replace-menu
+ '(" " "!" "^" "_" "$" "#" "*" "'") 0
+ (lambda (mark)
+ (case (string-to-char mark)
+ (? "( ) Nothing Special")
+ (?! "(!) Column Names")
+ (?^ "(^) Field Names Above")
+ (?_ "(^) Field Names Below")
+ (?$ "($) Formula Parameters")
+ (?# "(#) Recalculation: Auto")
+ (?* "(*) Recalculation: Manual")
+ (?' "(') Recalculation: None"))) t))))
+ ((assq :table contextlist)
+ (popup-menu
+ '(nil
+ ["Align Table" org-ctrl-c-ctrl-c]
+ ["Blank Field" org-table-blank-field]
+ ["Edit Field" org-table-edit-field]
+ "--"
+ ("Column"
+ ["Move Column Left" org-metaleft]
+ ["Move Column Right" org-metaright]
+ ["Delete Column" org-shiftmetaleft]
+ ["Insert Column" org-shiftmetaright]
+ "--"
+ ["Enable Narrowing" (setq org-table-limit-column-width (not org-table-limit-column-width)) :selected org-table-limit-column-width :style toggle])
+ ("Row"
+ ["Move Row Up" org-metaup]
+ ["Move Row Down" org-metadown]
+ ["Delete Row" org-shiftmetaup]
+ ["Insert Row" org-shiftmetadown]
+ ["Sort lines in region" org-table-sort-lines (org-at-table-p)]
+ "--"
+ ["Insert Hline" org-table-insert-hline])
+ ("Rectangle"
+ ["Copy Rectangle" org-copy-special]
+ ["Cut Rectangle" org-cut-special]
+ ["Paste Rectangle" org-paste-special]
+ ["Fill Rectangle" org-table-wrap-region])
+ "--"
+ ["Set Column Formula" org-table-eval-formula]
+ ["Set Field Formula" (org-table-eval-formula '(4))]
+ ["Edit Formulas" org-table-edit-formulas]
+ "--"
+ ["Recalculate Line" org-table-recalculate]
+ ["Recalculate All" (org-table-recalculate '(4))]
+ ["Iterate All" (org-table-recalculate '(16))]
+ "--"
+ ["Toggle Recalculate Mark" org-table-rotate-recalc-marks]
+ ["Sum Column/Rectangle" org-table-sum
+ :active (or (org-at-table-p) (org-region-active-p))]
+ ["Field Info" org-table-field-info]
+ ["Debug Formulas"
+ (setq org-table-formula-debug (not org-table-formula-debug))
+ :style toggle :selected org-table-formula-debug]
+ )))
+ ((and (assq :headline contextlist) (not (eolp)))
+ (let ((priority (org-mouse-get-priority t)))
+ (popup-menu
+ `("Headline Menu"
+ ("Tags and Priorities"
+ ,@(org-mouse-keyword-menu
+ (org-mouse-priority-list)
+ '(lambda (keyword)
+ (org-mouse-set-priority (string-to-char keyword)))
+ priority "Priority %s")
+ "--"
+ ,@(org-mouse-tag-menu))
+ ("TODO Status"
+ ,@(progn (org-mouse-match-todo-keyword)
+ (org-mouse-keyword-replace-menu (org-mouse-todo-keywords)
+ 1)))
+ ["Show Tags"
+ (with-current-buffer org-mouse-main-buffer (org-agenda-show-tags))
+ :visible (not org-mouse-direct)]
+ ["Show Priority"
+ (with-current-buffer org-mouse-main-buffer (org-agenda-show-priority))
+ :visible (not org-mouse-direct)]
+ ,@(if org-mouse-direct '("--") nil)
+ ["New Heading" org-mouse-insert-heading :visible org-mouse-direct]
+ ["Set Deadline"
+ (progn (org-mouse-end-headline) (insert " ") (org-deadline))
+ :active (not (save-excursion
+ (org-mouse-re-search-line org-deadline-regexp)))]
+ ["Schedule Task"
+ (progn (org-mouse-end-headline) (insert " ") (org-schedule))
+ :active (not (save-excursion
+ (org-mouse-re-search-line org-scheduled-regexp)))]
+ ["Insert Timestamp"
+ (progn (org-mouse-end-headline) (insert " ") (org-time-stamp nil)) t]
+; ["Timestamp (inactive)" org-time-stamp-inactive t]
+ "--"
+ ["Archive Subtree" org-archive-subtree]
+ ["Cut Subtree" org-cut-special]
+ ["Copy Subtree" org-copy-special]
+ ["Paste Subtree" org-paste-special :visible org-mouse-direct]
+ ("Sort Children"
+ ["Alphabetically" (org-sort-entries nil ?a)]
+ ["Numerically" (org-sort-entries nil ?n)]
+ ["By Time/Date" (org-sort-entries nil ?t)]
+ "--"
+ ["Reverse Alphabetically" (org-sort-entries nil ?A)]
+ ["Reverse Numerically" (org-sort-entries nil ?N)]
+ ["Reverse By Time/Date" (org-sort-entries nil ?T)])
+ "--"
+ ["Move Trees" org-mouse-move-tree :active nil]
+ ))))
+ (t
+ (org-mouse-popup-global-menu))))))
+
+;; (defun org-mouse-at-regexp (regexp)
+;; (save-excursion
+;; (let ((point (point))
+;; (bol (progn (beginning-of-line) (point)))
+;; (eol (progn (end-of-line) (point))))
+;; (goto-char point)
+;; (re-search-backward regexp bol 1)
+;; (and (not (eolp))
+;; (progn (forward-char)
+;; (re-search-forward regexp eol t))
+;; (<= (match-beginning 0) point)))))
+
+(defun org-mouse-mark-active ()
+ (and mark-active transient-mark-mode))
+
+(defun org-mouse-in-region-p (pos)
+ (and (org-mouse-mark-active)
+ (>= pos (region-beginning))
+ (< pos (region-end))))
+
+(defun org-mouse-down-mouse (event)
+ (interactive "e")
+ (setq this-command last-command)
+ (unless (and (= 1 (event-click-count event))
+ (org-mouse-in-region-p (posn-point (event-start event))))
+ (mouse-drag-region event)))
+
+(add-hook 'org-mode-hook
+ '(lambda ()
+ (setq org-mouse-context-menu-function 'org-mouse-context-menu)
+
+; (define-key org-mouse-map [follow-link] 'mouse-face)
+ (define-key org-mouse-map (if (featurep 'xemacs) [button3] [mouse-3]) nil)
+ (define-key org-mode-map [mouse-3] 'org-mouse-show-context-menu)
+ (define-key org-mode-map [down-mouse-1] 'org-mouse-down-mouse)
+ (define-key org-mouse-map [C-drag-mouse-1] 'org-mouse-move-tree)
+ (define-key org-mouse-map [C-down-mouse-1] 'org-mouse-move-tree-start)
+ (define-key org-mode-map [S-mouse-2] 'org-mouse-yank-link)
+ (define-key org-mode-map [drag-mouse-3] 'org-mouse-yank-link)
+ (define-key org-mouse-map [drag-mouse-3] 'org-mouse-move-tree)
+ (define-key org-mouse-map [down-mouse-3] 'org-mouse-move-tree-start)
+
+ (font-lock-add-keywords nil
+ `((,outline-regexp
+ 0 `(face org-link mouse-face highlight keymap ,org-mouse-map)
+ 'prepend)
+ ("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +"
+ (1 `(face org-link keymap ,org-mouse-map mouse-face highlight) 'prepend))
+ ("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(\\[[ X]\\]\\)"
+ (2 `(face bold keymap ,org-mouse-map mouse-face highlight) t)))
+ t)
+
+ (defadvice org-open-at-point (around org-mouse-open-at-point activate)
+ (let ((context (org-context)))
+ (cond
+ ((assq :headline-stars context) (org-cycle))
+ ((assq :checkbox context) (org-toggle-checkbox))
+ ((assq :item-bullet context)
+ (let ((org-cycle-include-plain-lists t)) (org-cycle)))
+ (t ad-do-it))))))
+
+(defun org-mouse-move-tree-start (event)
+ (interactive "e")
+ (message "Same line: promote/demote, (***):move before, (text): make a child"))
+
+
+(defun org-mouse-make-marker (position)
+ (with-current-buffer (window-buffer (posn-window position))
+ (copy-marker (posn-point position))))
+
+(defun org-mouse-move-tree (event)
+ ;; todo: handle movements between different buffers
+ (interactive "e")
+ (save-excursion
+ (let* ((start (org-mouse-make-marker (event-start event)))
+ (end (org-mouse-make-marker (event-end event)))
+ (sbuf (marker-buffer start))
+ (ebuf (marker-buffer end)))
+
+ (when (and sbuf ebuf)
+ (set-buffer sbuf)
+ (goto-char start)
+ (org-back-to-heading)
+ (if (and (eq sbuf ebuf)
+ (equal
+ (point)
+ (save-excursion (goto-char end) (org-back-to-heading) (point))))
+ ;; if the same line then promote/demote
+ (if (>= end start) (org-demote-subtree) (org-promote-subtree))
+ ;; if different lines then move
+ (org-cut-subtree)
+
+ (set-buffer ebuf)
+ (goto-char end)
+ (org-back-to-heading)
+ (when (and (eq sbuf ebuf)
+ (equal
+ (point)
+ (save-excursion (goto-char start)
+ (org-back-to-heading) (point))))
+ (outline-end-of-subtree)
+ (end-of-line)
+ (if (eobp) (newline) (forward-char)))
+
+ (when (looking-at outline-regexp)
+ (let ((level (- (match-end 0) (match-beginning 0))))
+ (when (> end (match-end 0))
+ (outline-end-of-subtree)
+ (end-of-line)
+ (if (eobp) (newline) (forward-char))
+ (setq level (1+ level)))
+ (org-paste-subtree level)
+ (save-excursion
+ (outline-end-of-subtree)
+ (when (bolp) (delete-char -1))))))))))
+
+
+(defun org-mouse-transform-to-outline ()
+ (interactive)
+ (org-back-to-heading)
+ (let ((minlevel 1000)
+ (replace-text (concat (match-string 0) "* ")))
+ (beginning-of-line 2)
+ (save-excursion
+ (while (not (or (eobp) (looking-at outline-regexp)))
+ (when (looking-at org-mouse-plain-list-regexp)
+ (setq minlevel (min minlevel (- (match-end 1) (match-beginning 1)))))
+ (forward-line)))
+ (while (not (or (eobp) (looking-at outline-regexp)))
+ (when (and (looking-at org-mouse-plain-list-regexp)
+ (eq minlevel (- (match-end 1) (match-beginning 1))))
+ (replace-match replace-text))
+ (forward-line))))
+
+(defvar _cmd) ;dynamically scoped from `org-with-remote-undo'.
+
+(defun org-mouse-do-remotely (command)
+; (org-agenda-check-no-diary)
+ (when (get-text-property (point) 'org-marker)
+ (let* ((anticol (- (point-at-eol) (point)))
+ (marker (get-text-property (point) 'org-marker))
+ (buffer (marker-buffer marker))
+ (pos (marker-position marker))
+ (hdmarker (get-text-property (point) 'org-hd-marker))
+ (buffer-read-only nil)
+ (newhead "--- removed ---")
+ (org-mouse-direct nil)
+ (org-mouse-main-buffer (current-buffer)))
+ (when (eq (with-current-buffer buffer major-mode) 'org-mode)
+ (let ((endmarker (save-excursion
+ (set-buffer buffer)
+ (outline-end-of-subtree)
+ (forward-char 1)
+ (copy-marker (point)))))
+ (org-with-remote-undo buffer
+ (with-current-buffer buffer
+ (widen)
+ (goto-char pos)
+ (org-show-hidden-entry)
+ (save-excursion
+ (and (outline-next-heading)
+ (org-flag-heading nil))) ; show the next heading
+ (org-back-to-heading)
+ (setq marker (copy-marker (point)))
+ (goto-char (max (point-at-bol) (- (point-at-eol) anticol)))
+ (funcall command)
+ (message "_cmd: %S" _cmd)
+ (message "this-command: %S" this-command)
+ (unless (eq (marker-position marker) (marker-position endmarker))
+ (setq newhead (org-get-heading))))
+
+ (beginning-of-line 1)
+ (save-excursion
+ (org-agenda-change-all-lines newhead hdmarker 'fixface))))
+ t))))
+
+(defun org-mouse-agenda-context-menu (&optional event)
+ (or (org-mouse-do-remotely 'org-mouse-context-menu)
+ (popup-menu
+ '("Agenda"
+ ("Agenda Files")
+ "--"
+ ["Undo" (progn (message "last command: %S" last-command) (setq this-command 'org-agenda-undo) (org-agenda-undo))
+ :visible (if (eq last-command 'org-agenda-undo)
+ org-agenda-pending-undo-list
+ org-agenda-undo-list)]
+ ["Rebuild Buffer" org-agenda-redo t]
+ ["New Diary Entry"
+ org-agenda-diary-entry (org-agenda-check-type nil 'agenda 'timeline) t]
+ "--"
+ ["Goto Today" org-agenda-goto-today
+ (org-agenda-check-type nil 'agenda 'timeline) t]
+ ["Display Calendar" org-agenda-goto-calendar
+ (org-agenda-check-type nil 'agenda 'timeline) t]
+ ("Calendar Commands"
+ ["Phases of the Moon" org-agenda-phases-of-moon
+ (org-agenda-check-type nil 'agenda 'timeline)]
+ ["Sunrise/Sunset" org-agenda-sunrise-sunset
+ (org-agenda-check-type nil 'agenda 'timeline)]
+ ["Holidays" org-agenda-holidays
+ (org-agenda-check-type nil 'agenda 'timeline)]
+ ["Convert" org-agenda-convert-date
+ (org-agenda-check-type nil 'agenda 'timeline)]
+ "--"
+ ["Create iCalendar file" org-export-icalendar-combine-agenda-files t])
+ "--"
+ ["Day View" org-agenda-day-view
+ :active (org-agenda-check-type nil 'agenda)
+ :style radio :selected (equal org-agenda-ndays 1)]
+ ["Week View" org-agenda-week-view
+ :active (org-agenda-check-type nil 'agenda)
+ :style radio :selected (equal org-agenda-ndays 7)]
+ "--"
+ ["Show Logbook entries" org-agenda-log-mode
+ :style toggle :selected org-agenda-show-log
+ :active (org-agenda-check-type nil 'agenda 'timeline)]
+ ["Include Diary" org-agenda-toggle-diary
+ :style toggle :selected org-agenda-include-diary
+ :active (org-agenda-check-type nil 'agenda)]
+ ["Use Time Grid" org-agenda-toggle-time-grid
+ :style toggle :selected org-agenda-use-time-grid
+ :active (org-agenda-check-type nil 'agenda)]
+ ["Follow Mode" org-agenda-follow-mode
+ :style toggle :selected org-agenda-follow-mode]
+ "--"
+ ["Quit" org-agenda-quit t]
+ ["Exit and Release Buffers" org-agenda-exit t]
+ ))))
+
+(defun org-mouse-get-gesture (event)
+ (let ((startxy (posn-x-y (event-start event)))
+ (endxy (posn-x-y (event-end event))))
+ (if (< (car startxy) (car endxy)) :right :left)))
+
+
+; (setq org-agenda-mode-hook nil)
+(add-hook 'org-agenda-mode-hook
+ '(lambda ()
+ (setq org-mouse-context-menu-function 'org-mouse-agenda-context-menu)
+ (define-key org-agenda-keymap
+ (if (featurep 'xemacs) [button3] [mouse-3])
+ 'org-mouse-show-context-menu)
+ (define-key org-agenda-keymap [down-mouse-3] 'org-mouse-move-tree-start)
+ (define-key org-agenda-keymap [C-mouse-4] 'org-agenda-earlier)
+ (define-key org-agenda-keymap [C-mouse-5] 'org-agenda-later)
+ (define-key org-agenda-keymap [drag-mouse-3]
+ '(lambda (event) (interactive "e")
+ (case (org-mouse-get-gesture event)
+ (:left (org-agenda-earlier 1))
+ (:right (org-agenda-later 1)))))))
+
+(provide 'org-mouse)
+
+;; arch-tag: ff1ae557-3529-41a3-95c6-baaebdcc280f
--- /dev/null
+;;; org-publish.el --- publish related org-mode files as a website
+
+;; Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
+
+;; Author: David O'Toole <dto@gnu.org>
+;; Maintainer: Bastien Guerry <bzg AT altern DOT org>
+;; Keywords: hypermedia, outlines, wp
+;; Version: 5.23a
+
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Requires at least version 4.27 of org.el
+
+;; This program allow configurable publishing of related sets of
+;; Org-mode files as a complete website.
+;;
+;; org-publish.el can do the following:
+;;
+;; + Publish all one's org-files to HTML or LaTeX
+;; + Upload HTML, images, attachments and other files to a web server
+;; + Exclude selected private pages from publishing
+;; + Publish a clickable index of pages
+;; + Manage local timestamps for publishing only changed files
+;; + Accept plugin functions to extend range of publishable content
+;;
+;; Special thanks to the org-mode maintainer Carsten Dominik for his
+;; ideas, enthusiasm, and cooperation.
+
+;;; Installation:
+
+;; Put org-publish.el in your load path, byte-compile it, and then add
+;; the following lines to your emacs initialization file:
+
+;; (autoload 'org-publish "org-publish" nil t)
+;; (autoload 'org-publish "org-publish-all" nil t)
+;; (autoload 'org-publish "org-publish-current-file" nil t)
+;; (autoload 'org-publish "org-publish-current-project" nil t)
+
+;; NOTE: When org-publish.el is included with org.el, those forms are
+;; already in the file org-install.el, and hence don't need to be put
+;; in your emacs initialization file in this case.
+
+;;; Usage:
+;;
+;; The program's main configuration variable is
+;; `org-publish-project-alist'. See below for example configurations
+;; with commentary.
+
+;; The main interactive functions are:
+;;
+;; M-x org-publish
+;; M-x org-publish-all
+;; M-x org-publish-current-file
+;; M-x org-publish-current-project
+
+;;;; Simple example configuration:
+
+;; (setq org-publish-project-alist
+;; (list
+;; '("org" . (:base-directory "~/org/"
+;; :base-extension "org"
+;; :publishing-directory "~/public_html"
+;; :with-section-numbers nil
+;; :table-of-contents nil
+;; :recursive t
+;; :style "<link rel=stylesheet href=\"../other/mystyle.css\" type=\"text/css\">")))
+
+;;;; More complex example configuration:
+
+;; Imagine your *.org files are kept in ~/org, your images in
+;; ~/images, and stylesheets in ~/other. Now imagine you want to
+;; publish the files through an ssh connection to a remote host, via
+;; Tramp-mode. To maintain relative links from *.org files to /images
+;; and /other, we should replicate the same directory structure in
+;; your web server account's designated html root (in this case,
+;; assumed to be ~/html)
+
+;; Once you've done created the proper directories, you can adapt the
+;; following example configuration to your specific paths, run M-x
+;; org-publish-all, and it should publish the files to the correct
+;; directories on the web server, transforming the *.org files into
+;; HTML, and leaving other files alone.
+
+;; (setq org-publish-project-alist
+;; (list
+;; '("orgfiles" :base-directory "~/org/"
+;; :base-extension "org"
+;; :publishing-directory "/ssh:user@host:~/html/notebook/"
+;; :publishing-function org-publish-org-to-html
+;; :exclude "PrivatePage.org" ;; regexp
+;; :headline-levels 3
+;; :with-section-numbers nil
+;; :table-of-contents nil
+;; :style "<link rel=stylesheet href=\"../other/mystyle.css\" type=\"text/css\">"
+;; :auto-preamble t
+;; :auto-postamble nil)
+;; ("images" :base-directory "~/images/"
+;; :base-extension "jpg\\|gif\\|png"
+;; :publishing-directory "/ssh:user@host:~/html/images/"
+;; :publishing-function org-publish-attachment)
+;; ("other" :base-directory "~/other/"
+;; :base-extension "css"
+;; :publishing-directory "/ssh:user@host:~/html/other/"
+;; :publishing-function org-publish-attachment)
+;; ("website" :components ("orgfiles" "images" "other"))))
+
+;; For more information, see the documentation for the variable
+;; `org-publish-project-alist'.
+
+;; Of course, you don't have to publish to remote directories from
+;; within emacs. You can always just publish to local folders, and
+;; then use the synchronization/upload tool of your choice.
+
+;;; List of user-visible changes since version 1.27
+
+;; 1.78: Allow list-valued :publishing-function
+;; 1.77: Added :preparation-function, this allows you to use GNU Make etc.
+;; 1.65: Remove old "composite projects". They're redundant.
+;; 1.64: Allow meta-projects with :components
+;; 1.57: Timestamps flag is now called "org-publish-use-timestamps-flag"
+;; 1.52: Properly set default for :index-filename
+;; 1.48: Composite projects allowed.
+;; :include keyword allowed.
+;; 1.43: Index no longer includes itself in the index.
+;; 1.42: Fix "function definition is void" error
+;; when :publishing-function not set in org-publish-current-file.
+;; 1.41: Fixed bug where index isn't published on first try.
+;; 1.37: Added interactive function "org-publish". Prompts for particular
+;; project name to publish.
+;; 1.34: Added force-publish option to all interactive functions.
+;; 1.32: Fixed "index.org has changed on disk" error during index publishing.
+;; 1.30: Fixed startup error caused by (require 'em-unix)
+
+;;; Code:
+
+(eval-when-compile
+ (require 'cl))
+
+(require 'dired-aux)
+
+(defgroup org-publish nil
+ "Options for publishing a set of Org-mode and related files."
+ :tag "Org Publishing"
+ :group 'org)
+
+(defcustom org-publish-project-alist nil
+ "Association list to control publishing behavior.
+Each element of the alist is a publishing 'project.' The CAR of
+each element is a string, uniquely identifying the project. The
+CDR of each element is in one of the following forms:
+
+ (:property value :property value ... )
+
+OR,
+
+ (:components (\"project-1\" \"project-2\" ...))
+
+When the CDR of an element of org-publish-project-alist is in
+this second form, the elements of the list after :components are
+taken to be components of the project, which group together files
+requiring different publishing options. When you publish such a
+project with M-x org-publish, the components all publish.
+
+When a property is given a value in org-publish-project-alist, its
+setting overrides the value of the corresponding user variable
+ (if any) during publishing. However, options set within a file
+override everything.
+
+Most properties are optional, but some should always be set:
+
+ :base-directory Directory containing publishing source files
+ :base-extension Extension (without the dot!) of source files.
+ This can be a regular expression.
+ :publishing-directory Directory (possibly remote) where output
+ files will be published
+
+The :exclude property may be used to prevent certain files from
+being published. Its value may be a string or regexp matching
+file names you don't want to be published.
+
+The :include property may be used to include extra files. Its
+value may be a list of filenames to include. The filenames are
+considered relative to the publishing directory.
+
+When both :include and :exclude properties are given values, the
+exclusion step happens first.
+
+One special property controls which back-end function to use for
+publishing files in the project. This can be used to extend the
+set of file types publishable by org-publish, as well as the set
+of output formats.
+
+ :publishing-function Function to publish file. The default is
+ org-publish-org-to-html, but other
+ values are possible. May also be a
+ list of functions, in which case
+ each function in the list is invoked
+ in turn.
+
+Another property allows you to insert code that prepares a
+project for publishing. For example, you could call GNU Make on a
+certain makefile, to ensure published files are built up to date.
+
+ :preparation-function Function to be called before publishing
+ this project.
+
+Some properties control details of the Org publishing process,
+and are equivalent to the corresponding user variables listed in
+the right column. See the documentation for those variables to
+learn more about their use and default values.
+
+ :language org-export-default-language
+ :headline-levels org-export-headline-levels
+ :section-numbers org-export-with-section-numbers
+ :table-of-contents org-export-with-toc
+ :emphasize org-export-with-emphasize
+ :sub-superscript org-export-with-sub-superscripts
+ :TeX-macros org-export-with-TeX-macros
+ :fixed-width org-export-with-fixed-width
+ :tables org-export-with-tables
+ :table-auto-headline org-export-highlight-first-table-line
+ :style org-export-html-style
+ :convert-org-links org-export-html-link-org-files-as-html
+ :inline-images org-export-html-inline-images
+ :expand-quoted-html org-export-html-expand
+ :timestamp org-export-html-with-timestamp
+ :publishing-directory org-export-publishing-directory
+ :preamble org-export-html-preamble
+ :postamble org-export-html-postamble
+ :auto-preamble org-export-html-auto-preamble
+ :auto-postamble org-export-html-auto-postamble
+ :author user-full-name
+ :email user-mail-address
+
+The following properties may be used to control publishing of an
+index of files or summary page for a given project.
+
+ :auto-index Whether to publish an index during
+ org-publish-current-project or org-publish-all.
+ :index-filename Filename for output of index. Defaults
+ to 'index.org' (which becomes 'index.html')
+ :index-title Title of index page. Defaults to name of file.
+ :index-function Plugin function to use for generation of index.
+ Defaults to 'org-publish-org-index', which
+ generates a plain list of links to all files
+ in the project."
+ :group 'org-publish
+ :type 'alist)
+
+(defcustom org-publish-use-timestamps-flag t
+ "When non-nil, use timestamp checking to publish only changed files.
+When nil, do no timestamp checking and always publish all
+files."
+ :group 'org-publish
+ :type 'boolean)
+
+(defcustom org-publish-timestamp-directory "~/.org-timestamps/"
+ "Name of directory in which to store publishing timestamps."
+ :group 'org-publish
+ :type 'directory)
+
+(defcustom org-publish-before-export-hook nil
+ "Hook run before export on the Org file.
+If the functions in this hook modify the original Org buffer, the
+modified buffer will be used for export, but the buffer will be
+restored and saved back to its initial state after export."
+ :group 'org-publish
+ :type 'hook)
+
+(defcustom org-publish-after-export-hook nil
+ "Hook run after export on the exported buffer.
+If functions in this hook modify the buffer, it will be saved."
+ :group 'org-publish
+ :type 'hook)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Timestamp-related functions
+
+(defun org-publish-timestamp-filename (filename)
+ "Return path to timestamp file for filename FILENAME."
+ (while (string-match
+ (if (eq system-type 'windows-nt) "~\\|/\\|:" "~\\|/") filename)
+ (setq filename (replace-match "_" nil t filename)))
+ (concat org-publish-timestamp-directory filename ".timestamp"))
+
+(defun org-publish-needed-p (filename)
+ "Return `t' if FILENAME should be published."
+ (if org-publish-use-timestamps-flag
+ (if (file-exists-p org-publish-timestamp-directory)
+ ;; first handle possible wrong timestamp directory
+ (if (not (file-directory-p org-publish-timestamp-directory))
+ (error "Org publish timestamp: %s is not a directory"
+ org-publish-timestamp-directory)
+ ;; there is a timestamp, check if FILENAME is newer
+ (file-newer-than-file-p
+ filename (org-publish-timestamp-filename filename))))
+ ;; don't use timestamps, always return t
+ t))
+
+(defun org-publish-update-timestamp (filename)
+ "Update publishing timestamp for file FILENAME.
+If there is no timestamp, create one."
+ (let ((timestamp-file (org-publish-timestamp-filename filename))
+ newly-created-timestamp)
+ (if (not (file-exists-p timestamp-file))
+ ;; create timestamp file if needed
+ (with-temp-buffer
+ (make-directory (file-name-directory timestamp-file) t)
+ (write-file timestamp-file)
+ (setq newly-created-timestamp t)))
+ ;; Emacs 21 doesn't have `set-file-times'
+ (if (and (fboundp 'set-file-times)
+ (not newly-created-timestamp))
+ (set-file-times timestamp-file)
+ (call-process "touch" nil 0 nil timestamp-file))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Mapping files to project names
+
+(defvar org-publish-files-alist nil
+ "Alist of files and their parent project.
+Each element of this alist is of the form:
+
+ (file-name . project-name)")
+
+(defun org-publish-initialize-files-alist (&optional refresh)
+ "Set `org-publish-files-alist' if it is not set.
+Also set it if the optional argument REFRESH is non-nil."
+ (interactive "P")
+ (when (or refresh (not org-publish-files-alist))
+ (setq org-publish-files-alist
+ (org-publish-get-files org-publish-project-alist))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Compatibility aliases
+
+;; Delete-dups is not in Emacs <22
+(if (fboundp 'delete-dups)
+ (defalias 'org-publish-delete-dups 'delete-dups)
+ (defun org-publish-delete-dups (list)
+ "Destructively remove `equal' duplicates from LIST.
+Store the result in LIST and return it. LIST must be a proper list.
+Of several `equal' occurrences of an element in LIST, the first
+one is kept.
+
+This is a compatibility function for Emacsen without `delete-dups'."
+ ;; Code from `subr.el' in Emacs 22:
+ (let ((tail list))
+ (while tail
+ (setcdr tail (delete (car tail) (cdr tail)))
+ (setq tail (cdr tail))))
+ list))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Getting project information out of org-publish-project-alist
+
+(defun org-publish-get-files (projects-alist &optional no-exclusion)
+ "Return the list of all publishable files for PROJECTS-ALIST.
+If NO-EXCLUSION is non-nil, don't exclude files."
+ (let (all-files)
+ ;; add all projects
+ (mapc
+ (lambda(p)
+ (let* ((exclude (plist-get (cdr p) :exclude))
+ (files (and p (org-publish-get-base-files p exclude))))
+ ;; add all files from this project
+ (mapc (lambda(f)
+ (add-to-list 'all-files
+ (cons (expand-file-name f) (car p))))
+ files)))
+ (org-publish-expand-projects projects-alist))
+ all-files))
+
+(defun org-publish-expand-projects (projects-alist)
+ "Expand projects contained in PROJECTS-ALIST."
+ (let (without-component with-component)
+ (mapc (lambda(p)
+ (add-to-list
+ (if (plist-get (cdr p) :components)
+ 'with-component 'without-component) p))
+ projects-alist)
+ (org-publish-delete-dups
+ (append without-component
+ (car (mapcar (lambda(p) (org-publish-expand-components p))
+ with-component))))))
+
+(defun org-publish-expand-components (project)
+ "Expand PROJECT into an alist of its components."
+ (let* ((components (plist-get (cdr project) :components)))
+ (org-publish-delete-dups
+ (delq nil (mapcar (lambda(c) (assoc c org-publish-project-alist))
+ components)))))
+
+(defun org-publish-get-base-files (project &optional exclude-regexp)
+ "Return a list of all files in PROJECT.
+If EXCLUDE-REGEXP is set, this will be used to filter out
+matching filenames."
+ (let* ((project-plist (cdr project))
+ (base-dir (file-name-as-directory
+ (plist-get project-plist :base-directory)))
+ (include-list (plist-get project-plist :include))
+ (recursive-p (plist-get project-plist :recursive))
+ (extension (or (plist-get project-plist :base-extension) "org"))
+ (regexp (concat "^[^\\.].*\\.\\(" extension "\\)$"))
+ alldirs allfiles files dir)
+ ;; Get all files and directories in base-directory
+ (setq files (dired-files-attributes base-dir))
+ ;; Get all subdirectories if recursive-p
+ (setq alldirs
+ (if recursive-p
+ (delq nil (mapcar (lambda(f) (if (caaddr f) (cadr f))) files))
+ (list base-dir)))
+ (while (setq dir (pop alldirs))
+ (setq files (directory-files dir t regexp))
+ ;; Exclude files
+ (setq files
+ (if (not exclude-regexp)
+ files
+ (delq nil
+ (mapcar (lambda (x)
+ (if (string-match exclude-regexp x) nil x))
+ files))))
+ ;; Include extra files
+ (let (inc)
+ (while (setq inc (pop include-list))
+ (setq files (cons (expand-file-name inc dir) files))))
+ (setq allfiles (append allfiles files)))
+ allfiles))
+
+(defun org-publish-get-project-from-filename (filename)
+ "Return the project FILENAME belongs."
+ (let* ((project-name (cdr (assoc (expand-file-name filename)
+ org-publish-files-alist))))
+ (assoc project-name org-publish-project-alist)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Pluggable publishing back-end functions
+
+(defun org-publish-org-to (format plist filename pub-dir)
+ "Publish an org file to FORMAT.
+PLIST is the property list for the given project.
+FILENAME is the filename of the org file to be published.
+PUB-DIR is the publishing directory."
+ (require 'org)
+ (unless (file-exists-p pub-dir)
+ (make-directory pub-dir t))
+ (find-file filename)
+ (let ((init-buf (current-buffer))
+ (init-point (point))
+ (init-buf-string (buffer-string)) export-buf)
+ ;; run hooks before exporting
+ (run-hooks 'org-publish-before-export-hook)
+ ;; export the possibly modified buffer
+ (setq export-buf
+ (funcall (intern (concat "org-export-as-" format))
+ (plist-get plist :headline-levels)
+ nil plist nil nil pub-dir))
+ (set-buffer export-buf)
+ ;; run hooks after export and save export
+ (and (run-hooks 'org-publish-after-export-hook)
+ (if (buffer-modified-p) (save-buffer)))
+ ;; maybe restore buffer's content
+ (set-buffer init-buf)
+ (when (buffer-modified-p init-buf)
+ (erase-buffer)
+ (insert init-buf-string)
+ (save-buffer)
+ (goto-char init-point))))
+
+(defun org-publish-org-to-latex (plist filename pub-dir)
+ "Publish an org file to LaTeX.
+See `org-publish-org-to' to the list of arguments."
+ (org-publish-org-to "latex" plist filename pub-dir))
+
+(defun org-publish-org-to-html (plist filename pub-dir)
+ "Publish an org file to HTML.
+See `org-publish-org-to' to the list of arguments."
+ (org-publish-org-to "html" plist filename pub-dir))
+
+(defun org-publish-attachment (plist filename pub-dir)
+ "Publish a file with no transformation of any kind.
+See `org-publish-org-to' to the list of arguments."
+ ;; make sure eshell/cp code is loaded
+ (eval-and-compile
+ (require 'eshell)
+ (require 'esh-maint)
+ (require 'em-unix))
+ (eshell/cp filename pub-dir))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Publishing files, sets of files, and indices
+
+(defun org-publish-file (filename &optional project)
+ "Publish file FILENAME from PROJECT."
+ (when (org-publish-needed-p filename)
+ (let* ((project
+ (or project
+ (or (org-publish-get-project-from-filename filename)
+ (if (y-or-n-p
+ (format "%s is not in a project. Re-read the list of projects files? "
+ (abbreviate-file-name filename)))
+ ;; If requested, re-initialize the list of projects files
+ (progn (org-publish-initialize-files-alist t)
+ (or (org-publish-get-project-from-filename filename)
+ (error "File %s not part of any known project"
+ (abbreviate-file-name filename))))
+ (error "Can't publish file outside of a project")))))
+ (project-plist (cdr project))
+ (publishing-function
+ (or (plist-get project-plist :publishing-function)
+ 'org-publish-org-to-html))
+ (base-dir (file-name-as-directory
+ (file-truename (plist-get project-plist :base-directory))))
+ (pub-dir (file-name-as-directory
+ (file-truename (plist-get project-plist :publishing-directory))))
+ tmp-pub-dir)
+ (setq tmp-pub-dir
+ (file-name-directory
+ (concat pub-dir
+ (and (string-match (regexp-quote base-dir) filename)
+ (substring filename (match-end 0))))))
+ (if (listp publishing-function)
+ ;; allow chain of publishing functions
+ (mapc (lambda (f)
+ (funcall f project-plist filename tmp-pub-dir))
+ publishing-function)
+ (funcall publishing-function project-plist filename tmp-pub-dir)))
+ (org-publish-update-timestamp filename)))
+
+(defun org-publish-projects (projects)
+ "Publish all files belonging to the PROJECTS alist.
+If :auto-index is set, publish the index too."
+ (mapc
+ (lambda (project)
+ (let* ((project-plist (cdr project))
+ (exclude-regexp (plist-get project-plist :exclude))
+ (index-p (plist-get project-plist :auto-index))
+ (index-filename (or (plist-get project-plist :index-filename)
+ "index.org"))
+ (index-function (or (plist-get project-plist :index-function)
+ 'org-publish-org-index))
+ (preparation-function (plist-get project-plist :preparation-function))
+ (files (org-publish-get-base-files project exclude-regexp)) file)
+ (when preparation-function (funcall preparation-function))
+ (if index-p (funcall index-function project index-filename))
+ (while (setq file (pop files))
+ (org-publish-file file project))))
+ (org-publish-expand-projects projects)))
+
+(defun org-publish-org-index (project &optional index-filename)
+ "Create an index of pages in set defined by PROJECT.
+Optionally set the filename of the index with INDEX-FILENAME.
+Default for INDEX-FILENAME is 'index.org'."
+ (let* ((project-plist (cdr project))
+ (dir (file-name-as-directory
+ (plist-get project-plist :base-directory)))
+ (exclude-regexp (plist-get project-plist :exclude))
+ (files (org-publish-get-base-files project exclude-regexp))
+ (index-filename (concat dir (or index-filename "index.org")))
+ (index-buffer (find-buffer-visiting index-filename))
+ (ifn (file-name-nondirectory index-filename))
+ file)
+ ;; if buffer is already open, kill it to prevent error message
+ (if index-buffer
+ (kill-buffer index-buffer))
+ (with-temp-buffer
+ (while (setq file (pop files))
+ (let ((fn (file-name-nondirectory file)))
+ ;; index shouldn't index itself
+ (unless (string= fn ifn)
+ (insert (concat " + [[file:" fn "]["
+ (file-name-sans-extension fn)
+ "]]\n")))))
+ (write-file index-filename)
+ (kill-buffer (current-buffer)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Interactive publishing functions
+
+(defalias 'org-publish-project 'org-publish "Publish project.")
+
+;;;###autoload
+(defun org-publish (project &optional force)
+ "Publish PROJECT."
+ (interactive "P")
+ (save-window-excursion
+ (let* ((force current-prefix-arg)
+ (org-publish-use-timestamps-flag
+ (if force nil org-publish-use-timestamps-flag)))
+ (org-publish-projects
+ (list (or project
+ (assoc (completing-read
+ "Publish project: "
+ org-publish-project-alist nil t)
+ org-publish-project-alist)))))))
+
+;;;###autoload
+(defun org-publish-all (&optional force)
+ "Publish all projects.
+With prefix argument, force publish all files."
+ (interactive "P")
+ (org-publish-initialize-files-alist)
+ (save-window-excursion
+ (let ((org-publish-use-timestamps-flag
+ (if force nil org-publish-use-timestamps-flag)))
+ (org-publish-projects org-publish-project-alist))))
+
+;;;###autoload
+(defun org-publish-current-file (&optional force)
+ "Publish the current file.
+With prefix argument, force publish the file."
+ (interactive "P")
+ (org-publish-initialize-files-alist)
+ (save-window-excursion
+ (let ((org-publish-use-timestamps-flag
+ (if force nil org-publish-use-timestamps-flag)))
+ (org-publish-file (buffer-file-name)))))
+
+;;;###autoload
+(defun org-publish-current-project (&optional force)
+ "Publish the project associated with the current file.
+With a prefix argument, force publishing of all files in
+the project."
+ (interactive "P")
+ (org-publish-initialize-files-alist)
+ (save-window-excursion
+ (let ((project (org-publish-get-project-from-filename (buffer-file-name)))
+ (org-publish-use-timestamps-flag
+ (if force nil org-publish-use-timestamps-flag)))
+ (if (not project)
+ (error "File %s is not part of any known project" (buffer-file-name)))
+ (org-publish project))))
+
+(provide 'org-publish)
+
+
+;; arch-tag: 72807f3c-8af0-4a6b-8dca-c3376eb25adb
+;;; org-publish.el ends here
-;;;; org.el --- Outline-based notes management and organize
+;;; org.el --- Outline-based notes management and organizer
;; Carstens outline-mode for keeping track of everything.
;; Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
;;
-;; Author: Carsten Dominik <dominik at science dot uva dot nl>
+;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
-;; Homepage: http://www.astro.uva.nl/~dominik/Tools/org/
-;; Version: 4.67d
+;; Homepage: http://orgmode.org
+;; Version: 5.23a
;;
;; This file is part of GNU Emacs.
;;
;; ---------------------------
;; See the corresponding sections in the manual at
;;
-;; http://staff.science.uva.nl/~dominik/Tools/org/org.html#Installation
+;; http://orgmode.org/org.html#Installation
;;
;; Documentation
;; -------------
;; in the etc/ directory of Emacs 22.
;;
;; A list of recent changes can be found at
-;; http://www.astro.uva.nl/~dominik/Tools/org/Changes
+;; http://orgmode.org/Changes.html
;;
;;; Code:
(require 'outline) (require 'noutline)
;; Other stuff we need.
(require 'time-date)
+(unless (fboundp 'time-subtract) (defalias 'time-subtract 'subtract-time))
(require 'easymenu)
;;;; Customization variables
;;; Version
-(defvar org-version "4.67c"
+(defconst org-version "5.23a"
"The version number of the file org.el.")
-(defun org-version ()
- (interactive)
- (message "Org-mode version %s" org-version))
+
+(defun org-version (&optional here)
+ "Show the org-mode version in the echo area.
+With prefix arg HERE, insert it at point."
+ (interactive "P")
+ (let ((version (format "Org-mode version %s" org-version)))
+ (message version)
+ (if here
+ (insert version))))
;;; Compatibility constants
(defconst org-xemacs-p (featurep 'xemacs)) ; not used by org.el itself
(get-text-property 0 'test (format "%s" x)))
"Does format transport text properties?")
+(defmacro org-bound-and-true-p (var)
+ "Return the value of symbol VAR if it is bound, else nil."
+ `(and (boundp (quote ,var)) ,var))
+
+(defmacro org-unmodified (&rest body)
+ "Execute body without changing `buffer-modified-p'."
+ `(set-buffer-modified-p
+ (prog1 (buffer-modified-p) ,@body)))
+
+(defmacro org-re (s)
+ "Replace posix classes in regular expression."
+ (if (featurep 'xemacs)
+ (let ((ss s))
+ (save-match-data
+ (while (string-match "\\[:alnum:\\]" ss)
+ (setq ss (replace-match "a-zA-Z0-9" t t ss)))
+ (while (string-match "\\[:alpha:\\]" ss)
+ (setq ss (replace-match "a-zA-Z" t t ss)))
+ ss))
+ s))
+
+(defmacro org-preserve-lc (&rest body)
+ `(let ((_line (org-current-line))
+ (_col (current-column)))
+ (unwind-protect
+ (progn ,@body)
+ (goto-line _line)
+ (move-to-column _col))))
+
+(defmacro org-without-partial-completion (&rest body)
+ `(let ((pc-mode (and (boundp 'partial-completion-mode)
+ partial-completion-mode)))
+ (unwind-protect
+ (progn
+ (if pc-mode (partial-completion-mode -1))
+ ,@body)
+ (if pc-mode (partial-completion-mode 1)))))
+
;;; The custom variables
(defgroup org nil
:group 'hypermedia
:group 'calendar)
+(defcustom org-load-hook nil
+ "Hook that is run after org.el has been loaded."
+ :group 'org
+ :type 'hook)
+
+;(defcustom org-default-extensions '(org-irc)
+; "Extensions that should always be loaded together with org.el.
+;If the description starts with <A>, this means the extension
+;will be autoloaded when needed, preloading is not necessary.
+;FIXME: this does not ork correctly, ignore it for now."
+; :group 'org
+; :type
+; '(set :greedy t
+; (const :tag " Mouse support (org-mouse.el)" org-mouse)
+; (const :tag "<A> Publishing (org-publish.el)" org-publish)
+; (const :tag "<A> LaTeX export (org-export-latex.el)" org-export-latex)
+; (const :tag " IRC/ERC links (org-irc.el)" org-irc)
+; (const :tag " Apple Mail message links under OS X (org-mac-message.el)" org-mac-message)))
+;
+;(defun org-load-default-extensions ()
+; "Load all extensions listed in `org-default-extensions'."
+; (mapc (lambda (ext)
+; (condition-case nil (require ext)
+; (error (message "Problems while trying to load feature `%s'" ext))))
+; org-default-extensions))
+
+;(eval-after-load "org" '(org-load-default-extensions))
+
+;; FIXME: Needs a separate group...
+(defcustom org-completion-fallback-command 'hippie-expand
+ "The expansion command called by \\[org-complete] in normal context.
+Normal means, no org-mode-specific context."
+ :group 'org
+ :type 'function)
+
(defgroup org-startup nil
"Options concerning startup of Org-mode."
:tag "Org Startup"
:group 'org-startup
:type 'boolean)
-(defcustom org-CUA-compatible nil
- "Non-nil means use alternative key bindings for S-<cursor movement>.
-Org-mode used S-<cursor movement> for changing timestamps and priorities.
-S-<cursor movement> is also used for example by `CUA-mode' to select text.
-If you want to use Org-mode together with `CUA-mode', Org-mode needs to use
-alternative bindings. Setting this variable to t will replace the following
-keys both in Org-mode and in the Org-agenda buffer.
-
-S-RET -> C-S-RET
-S-up -> M-p
-S-down -> M-n
-S-left -> M--
-S-right -> M-+
-
-If you do not like the alternative keys, take a look at the variable
+(defcustom org-replace-disputed-keys nil
+ "Non-nil means use alternative key bindings for some keys.
+Org-mode uses S-<cursor> keys for changing timestamps and priorities.
+These keys are also used by other packages like `CUA-mode' or `windmove.el'.
+If you want to use Org-mode together with one of these other modes,
+or more generally if you would like to move some Org-mode commands to
+other keys, set this variable and configure the keys with the variable
`org-disputed-keys'.
This option is only relevant at load-time of Org-mode, and must be set
:group 'org-startup
:type 'boolean)
-(defvar org-disputed-keys
- '((S-up [(shift up)] [(meta ?p)])
- (S-down [(shift down)] [(meta ?n)])
- (S-left [(shift left)] [(meta ?-)])
- (S-right [(shift right)] [(meta ?+)])
- (S-return [(shift return)] [(control shift return)]))
+(if (fboundp 'defvaralias)
+ (defvaralias 'org-CUA-compatible 'org-replace-disputed-keys))
+
+(defcustom org-disputed-keys
+ '(([(shift up)] . [(meta p)])
+ ([(shift down)] . [(meta n)])
+ ([(shift left)] . [(meta -)])
+ ([(shift right)] . [(meta +)])
+ ([(control shift right)] . [(meta shift +)])
+ ([(control shift left)] . [(meta shift -)]))
"Keys for which Org-mode and other modes compete.
-This is an alist, cars are symbols for lookup, 1st element is the default key,
-second element will be used when `org-CUA-compatible' is t.")
+This is an alist, cars are the default keys, second element specifies
+the alternative to use when `org-replace-disputed-keys' is t.
+
+Keys can be specified in any syntax supported by `define-key'.
+The value of this option takes effect only at Org-mode's startup,
+therefore you'll have to restart Emacs to apply it after changing."
+ :group 'org-startup
+ :type 'alist)
(defun org-key (key)
- "Select a key according to `org-CUA-compatible'."
- (nth (if org-CUA-compatible 2 1)
- (or (assq key org-disputed-keys)
- (error "Invalid Key %s in `org-key'" key))))
+ "Select key according to `org-replace-disputed-keys' and `org-disputed-keys'.
+Or return the original if not disputed."
+ (if org-replace-disputed-keys
+ (let* ((nkey (key-description key))
+ (x (org-find-if (lambda (x)
+ (equal (key-description (car x)) nkey))
+ org-disputed-keys)))
+ (if x (cdr x) key))
+ key))
+
+(defun org-find-if (predicate seq)
+ (catch 'exit
+ (while seq
+ (if (funcall predicate (car seq))
+ (throw 'exit (car seq))
+ (pop seq)))))
+
+(defun org-defkey (keymap key def)
+ "Define a key, possibly translated, as returned by `org-key'."
+ (define-key keymap (org-key key) def))
(defcustom org-ellipsis nil
"The ellipsis to use in the Org-mode outline.
When nil, just use the standard three dots. When a string, use that instead,
-and just in Org-mode (which will then use its own display table).
+When a face, use the standart 3 dots, but with the specified face.
+The change affects only Org-mode (which will then use its own display table).
Changing this requires executing `M-x org-mode' in a buffer to become
effective."
:group 'org-startup
:type '(choice (const :tag "Default" nil)
+ (face :tag "Face" :value org-warning)
(string :tag "String" :value "...#")))
(defvar org-display-table nil
:group 'org-keywords
:type 'string)
-(defvar org-repeat-re "\\<REPEAT(\\([-+ 0-9dwmy]+\\))"
+(defconst org-repeat-re
+ "<[0-9]\\{4\\}-[0-9][0-9]-[0-9][0-9] [^>\n]*\\([.+]?\\+[0-9]+[dwmy]\\)"
"Regular expression for specifying repeated events.
After a match, group 1 contains the repeat expression.")
:tag "Org Reveal Location"
:group 'org-structure)
+(defconst org-context-choice
+ '(choice
+ (const :tag "Always" t)
+ (const :tag "Never" nil)
+ (repeat :greedy t :tag "Individual contexts"
+ (cons
+ (choice :tag "Context"
+ (const agenda)
+ (const org-goto)
+ (const occur-tree)
+ (const tags-tree)
+ (const link-search)
+ (const mark-goto)
+ (const bookmark-jump)
+ (const isearch)
+ (const default))
+ (boolean))))
+ "Contexts for the reveal options.")
+
(defcustom org-show-hierarchy-above '((default . t))
"Non-nil means, show full hierarchy when revealing a location.
Org-mode often shows locations in an org-mode file which might have
isearch when exiting from an incremental search
default default for all contexts not set explicitly"
:group 'org-reveal-location
- :type '(choice
- (const :tag "Always" t)
- (const :tag "Never" nil)
- (repeat :greedy t :tag "Individual contexts"
- (cons
- (choice :tag "Context"
- (const agenda)
- (const org-goto)
- (const occur-tree)
- (const tags-tree)
- (const link-search)
- (const mark-goto)
- (const bookmark-jump)
- (const isearch)
- (const default))
- (boolean)))))
+ :type org-context-choice)
-(defcustom org-show-following-heading '((default . t))
+(defcustom org-show-following-heading '((default . nil))
"Non-nil means, show following heading when revealing a location.
Org-mode often shows locations in an org-mode file which might have
been invisible before. When this is set, the heading following the
Instead of t, this can also be an alist specifying this option for different
contexts. See `org-show-hierarchy-above' for valid contexts."
:group 'org-reveal-location
- :type '(choice
- (const :tag "Always" t)
- (const :tag "Never" nil)
- (repeat :greedy t :tag "Individual contexts"
- (cons
- (choice :tag "Context"
- (const agenda)
- (const org-goto)
- (const occur-tree)
- (const tags-tree)
- (const link-search)
- (const mark-goto)
- (const bookmark-jump)
- (const isearch)
- (const default))
- (boolean)))))
+ :type org-context-choice)
(defcustom org-show-siblings '((default . nil) (isearch t))
"Non-nil means, show all sibling heading when revealing a location.
Instead of t, this can also be an alist specifying this option for different
contexts. See `org-show-hierarchy-above' for valid contexts."
:group 'org-reveal-location
- :type '(choice
- (const :tag "Always" t)
- (const :tag "Never" nil)
- (repeat :greedy t :tag "Individual contexts"
- (cons
- (choice :tag "Context"
- (const agenda)
- (const org-goto)
- (const occur-tree)
- (const tags-tree)
- (const link-search)
- (const mark-goto)
- (const bookmark-jump)
- (const isearch)
- (const default))
- (boolean)))))
+ :type org-context-choice)
+
+(defcustom org-show-entry-below '((default . nil))
+ "Non-nil means, show the entry below a headline when revealing a location.
+Org-mode often shows locations in an org-mode file which might have
+been invisible before. When this is set, the text below the headline that is
+exposed is also shown.
+
+By default this is off for all contexts.
+Instead of t, this can also be an alist specifying this option for different
+contexts. See `org-show-hierarchy-above' for valid contexts."
+ :group 'org-reveal-location
+ :type org-context-choice)
(defgroup org-cycle nil
"Options concerning visibility cycling in Org-mode."
:tag "Org Cycle"
:group 'org-structure)
-(defcustom org-cycle-global-at-bob t
+(defcustom org-drawers '("PROPERTIES" "CLOCK")
+ "Names of drawers. Drawers are not opened by cycling on the headline above.
+Drawers only open with a TAB on the drawer line itself. A drawer looks like
+this:
+ :DRAWERNAME:
+ .....
+ :END:
+The drawer \"PROPERTIES\" is special for capturing properties through
+the property API.
+
+Drawers can be defined on the per-file basis with a line like:
+
+#+DRAWERS: HIDDEN STATE PROPERTIES"
+ :group 'org-structure
+ :type '(repeat (string :tag "Drawer Name")))
+
+(defcustom org-cycle-global-at-bob nil
"Cycle globally if cursor is at beginning of buffer and not at a headline.
This makes it possible to do global cycling without having to use S-TAB or
C-u TAB. For this special case to work, the first line of the buffer
"Where should `org-cycle' emulate TAB.
nil Never
white Only in completely white lines
-whitestart Only at the beginning of lines, before the first non-white char.
+whitestart Only at the beginning of lines, before the first non-white char
t Everywhere except in headlines
+exc-hl-bol Everywhere except at the start of a headline
If TAB is used in a place where it does not emulate TAB, the current subtree
visibility is cycled."
:group 'org-cycle
(const :tag "Only in completely white lines" white)
(const :tag "Before first char in a line" whitestart)
(const :tag "Everywhere except in headlines" t)
+ (const :tag "Everywhere except at bol in headlines" exc-hl-bol)
))
+(defcustom org-cycle-separator-lines 2
+ "Number of empty lines needed to keep an empty line between collapsed trees.
+If you leave an empty line between the end of a subtree and the following
+headline, this empty line is hidden when the subtree is folded.
+Org-mode will leave (exactly) one empty line visible if the number of
+empty lines is equal or larger to the number given in this variable.
+So the default 2 means, at least 2 empty lines after the end of a subtree
+are needed to produce free space between a collapsed subtree and the
+following headline.
+
+Special case: when 0, never leave empty lines in collapsed view."
+ :group 'org-cycle
+ :type 'integer)
+
(defcustom org-cycle-hook '(org-cycle-hide-archived-subtrees
+ org-cycle-hide-drawers
+ org-cycle-show-empty-lines
org-optimize-window-after-visibility-change)
"Hook that is run after `org-cycle' has changed the buffer visibility.
The function(s) in this hook must accept a single argument which indicates
:group 'org-cycle
:type 'hook)
-
(defgroup org-edit-structure nil
"Options concerning structure editing in Org-mode."
:tag "Org Edit Structure"
:group 'org-edit-structure
:type 'boolean)
+(defcustom org-special-ctrl-a/e nil
+ "Non-nil means `C-a' and `C-e' behave specially in headlines and items.
+When t, `C-a' will bring back the cursor to the beginning of the
+headline text, i.e. after the stars and after a possible TODO keyword.
+In an item, this will be the position after the bullet.
+When the cursor is already at that position, another `C-a' will bring
+it to the beginning of the line.
+`C-e' will jump to the end of the headline, ignoring the presence of tags
+in the headline. A second `C-e' will then jump to the true end of the
+line, after any tags.
+When set to the symbol `reversed', the first `C-a' or `C-e' works normally,
+and only a directly following, identical keypress will bring the cursor
+to the special positions."
+ :group 'org-edit-structure
+ :type '(choice
+ (const :tag "off" nil)
+ (const :tag "after bullet first" t)
+ (const :tag "border first" reversed)))
+
+(if (fboundp 'defvaralias)
+ (defvaralias 'org-special-ctrl-a 'org-special-ctrl-a/e))
+
+(defcustom org-special-ctrl-k nil
+ "Non-nil means `C-k' will behave specially in headlines.
+When nil, `C-k' will call the default `kill-line' command.
+When t, the following will happen while the cursor is in the headline:
+
+- When the cursor is at the beginning of a headline, kill the entire
+ line and possible the folded subtree below the line.
+- When in the middle of the headline text, kill the headline up to the tags.
+- When after the headline text, kill the tags."
+ :group 'org-edit-structure
+ :type 'boolean)
+
+(defcustom org-M-RET-may-split-line '((default . t))
+ "Non-nil means, M-RET will split the line at the cursor position.
+When nil, it will go to the end of the line before making a
+new line.
+You may also set this option in a different way for different
+contexts. Valid contexts are:
+
+headline when creating a new headline
+item when creating a new item
+table in a table field
+default the value to be used for all contexts not explicitly
+ customized"
+ :group 'org-structure
+ :group 'org-table
+ :type '(choice
+ (const :tag "Always" t)
+ (const :tag "Never" nil)
+ (repeat :greedy t :tag "Individual contexts"
+ (cons
+ (choice :tag "Context"
+ (const headline)
+ (const item)
+ (const table)
+ (const default))
+ (boolean)))))
+
+
(defcustom org-blank-before-new-entry '((heading . nil)
(plain-list-item . nil))
"Should `org-insert-heading' leave a blank line before new heading/item?
(defcustom org-insert-heading-hook nil
"Hook being run after inserting a new heading."
:group 'org-edit-structure
- :type 'boolean)
+ :type 'hook)
(defcustom org-enable-fixed-width-editor t
"Non-nil means, lines starting with \":\" are treated as fixed-width.
:group 'org-edit-structure
:type 'boolean)
+(defcustom org-goto-auto-isearch t
+ "Non-nil means, typing characters in org-goto starts incremental search."
+ :group 'org-edit-structure
+ :type 'boolean)
+
(defgroup org-sparse-trees nil
"Options concerning sparse trees in Org-mode."
:tag "Org Sparse Trees"
(defcustom org-archive-tag "ARCHIVE"
"The tag that marks a subtree as archived.
An archived subtree does not open during visibility cycling, and does
-not contribute to the agenda listings."
+not contribute to the agenda listings.
+After changing this, font-lock must be restarted in the relevant buffers to
+get the proper fontification."
:group 'org-archive
:group 'org-keywords
:type 'string)
:type 'string)
(defcustom org-archive-mark-done t
- "Non-nil means, mark entries as DONE when they are moved to the archive file."
+ "Non-nil means, mark entries as DONE when they are moved to the archive file.
+This can be a string to set the keyword to use. When t, Org-mode will
+use the first keyword in its list that means done."
:group 'org-archive
- :type 'boolean)
+ :type '(choice
+ (const :tag "No" nil)
+ (const :tag "Yes" t)
+ (string :tag "Use this keyword")))
(defcustom org-archive-stamp-time t
"Non-nil means, add a time stamp to entries moved to an archive file.
-The time stamp will be added directly after the TODO state keyword in the
-first line, so it is probably best to use this in combinations with
-`org-archive-mark-done'."
+This variable is obsolete and has no effect anymore, instead add ot remove
+`time' from the variablle `org-archive-save-context-info'."
:group 'org-archive
:type 'boolean)
+(defcustom org-archive-save-context-info '(time file olpath category todo itags)
+ "Parts of context info that should be stored as properties when archiving.
+When a subtree is moved to an archive file, it looses information given by
+context, like inherited tags, the category, and possibly also the TODO
+state (depending on the variable `org-archive-mark-done').
+This variable can be a list of any of the following symbols:
+
+time The time of archiving.
+file The file where the entry originates.
+itags The local tags, in the headline of the subtree.
+ltags The tags the subtree inherits from further up the hierarchy.
+todo The pre-archive TODO state.
+category The category, taken from file name or #+CATEGORY lines.
+olpath The outline path to the item. These are all headlines above
+ the current item, separated by /, like a file path.
+
+For each symbol present in the list, a property will be created in
+the archived entry, with a prefix \"PRE_ARCHIVE_\", to remember this
+information."
+ :group 'org-archive
+ :type '(set :greedy t
+ (const :tag "Time" time)
+ (const :tag "File" file)
+ (const :tag "Category" category)
+ (const :tag "TODO state" todo)
+ (const :tag "TODO state" priority)
+ (const :tag "Inherited tags" itags)
+ (const :tag "Outline path" olpath)
+ (const :tag "Local tags" ltags)))
+
+(defgroup org-imenu-and-speedbar nil
+ "Options concerning imenu and speedbar in Org-mode."
+ :tag "Org Imenu and Speedbar"
+ :group 'org-structure)
+
+(defcustom org-imenu-depth 2
+ "The maximum level for Imenu access to Org-mode headlines.
+This also applied for speedbar access."
+ :group 'org-imenu-and-speedbar
+ :type 'number)
+
(defgroup org-table nil
"Options concerning tables in Org-mode."
:tag "Org Table"
:type 'string)
(defcustom org-table-number-regexp
- "^\\([<>]?[-+^.0-9]*[0-9][-+^.0-9eEdDx()%:]*\\|\\(0[xX]\\)[0-9a-fA-F]+\\)$"
+ "^\\([<>]?[-+^.0-9]*[0-9][-+^.0-9eEdDx()%:]*\\|\\(0[xX]\\)[0-9a-fA-F]+\\|nan\\)$"
"Regular expression for recognizing numbers in table columns.
If a table column contains mostly numbers, it will be aligned to the
right. If not, it will be aligned to the left.
(const :tag "Exponential, Floating point, Integer"
"^[-+]?[0-9.]+\\([eEdD][-+0-9]+\\)?$")
(const :tag "Very General Number-Like, including hex"
- "^\\([<>]?[-+^.0-9]*[0-9][-+^.0-9eEdDx()%]*\\|\\(0[xX]\\)[0-9a-fA-F]+\\)$")
+ "^\\([<>]?[-+^.0-9]*[0-9][-+^.0-9eEdDx()%]*\\|\\(0[xX]\\)[0-9a-fA-F]+\\|nan\\)$")
(string :tag "Regexp:")))
(defcustom org-table-number-fraction 0.5
:type 'number)
(defgroup org-table-editing nil
- "Bahavior of tables during editing in Org-mode."
+ "Behavior of tables during editing in Org-mode."
:tag "Org Table Editing"
:group 'org-table)
:tag "Org Table Calculation"
:group 'org-table)
+(defcustom org-table-use-standard-references t
+ "Should org-mode work with table refrences like B3 instead of @3$2?
+Possible values are:
+nil never use them
+from accept as input, do not present for editing
+t: accept as input and present for editing"
+ :group 'org-table-calculation
+ :type '(choice
+ (const :tag "Never, don't even check unser input for them" nil)
+ (const :tag "Always, both as user input, and when editing" t)
+ (const :tag "Convert user input, don't offer during editing" 'from)))
+
(defcustom org-table-copy-increment t
"Non-nil means, increment when copying current field with \\[org-table-copy-down]."
:group 'org-table-calculation
:group 'org-table-calculation
:type 'boolean)
-;; FIXME this is also a variable that makes Org-mode files non-portable
-;; Maybe I should have a #+ options for constants?
-;; How about the SI/cgs issue?
(defcustom org-table-formula-use-constants t
"Non-nil means, interpret constants in formulas in tables.
A constant looks like `$c' or `$Grav' and will be replaced before evaluation
(setq org-table-formula-constants '((\"c\" . \"299792458.\")))
-and then use it in an equation like `$1*$c'."
+and then use it in an equation like `$1*$c'.
+
+Constants can also be defined on a per-file basis using a line like
+
+#+CONSTANTS: c=299792458. pi=3.14 eps=2.4e-6"
:group 'org-table-calculation
:type '(repeat
(cons (string :tag "name")
(string :tag "value"))))
+(defvar org-table-formula-constants-local nil
+ "Local version of `org-table-formula-constants'.")
+(make-variable-buffer-local 'org-table-formula-constants-local)
+
(defcustom org-table-allow-automatic-line-recalculation t
"Non-nil means, lines marked with |#| or |*| will be recomputed automatically.
Automatically means, when TAB or RET or C-c C-c are pressed in the line."
:group 'org)
(defvar org-link-abbrev-alist-local nil
- "buffer-local version of `org-link-abbrev-alist', which see.
+ "Buffer-local version of `org-link-abbrev-alist', which see.
The value of this is taken from the #+LINK lines.")
(make-variable-buffer-local 'org-link-abbrev-alist-local)
[[linkkey:tag][description]]
If REPLACE is a string, the tag will simply be appended to create the link.
-If the string contains \"%s\", the tag will be inserted there. REPLACE may
-also be a function that will be called with the tag as the only argument to
-create the link. See the manual for examples."
+If the string contains \"%s\", the tag will be inserted there.
+
+REPLACE may also be a function that will be called with the tag as the
+only argument to create the link, which should be returned as a string.
+
+See the manual for examples."
:group 'org-link
:type 'alist)
(defcustom org-descriptive-links t
"Non-nil means, hide link part and only show description of bracket links.
-Bracket links are like [[link][descritpion]]. This variable sets the initial
+Bracket links are like [[link][descritpion]]. This variable sets the initial
state in new org-mode buffers. The setting can then be toggled on a
per-buffer basis from the Org->Hyperlinks menu."
:group 'org-link
"How the path name in file links should be stored.
Valid values are:
-relative relative to the current directory, i.e. the directory of the file
+relative Relative to the current directory, i.e. the directory of the file
into which the link is being inserted.
-absolute absolute path, if possible with ~ for home directory.
-noabbrev absolute path, no abbreviation of home directory.
+absolute Absolute path, if possible with ~ for home directory.
+noabbrev Absolute path, no abbreviation of home directory.
adaptive Use relative path for files in the current directory and sub-
directories of it. For other files, use an absolute path."
:group 'org-link
:group 'org-link
:type '(set (const :tag "Double bracket links (new style)" bracket)
(const :tag "Angular bracket links (old style)" angular)
- (const :tag "plain text links" plain)
+ (const :tag "Plain text links" plain)
(const :tag "Radio target matches" radio)
(const :tag "Tags" tag)
(const :tag "Timestamps" date)))
(defgroup org-link-store nil
- "Options concerning storing links in Org-mode"
+ "Options concerning storing links in Org-mode."
:tag "Org Store Link"
:group 'org-link)
:type 'boolean)
(defgroup org-link-follow nil
- "Options concerning following links in Org-mode"
+ "Options concerning following links in Org-mode."
:tag "Org Follow Link"
:group 'org-link)
+(defcustom org-follow-link-hook nil
+ "Hook that is run after a link has been followed."
+ :group 'org-link-follow
+ :type 'hook)
+
(defcustom org-tab-follows-link nil
"Non-nil means, on links TAB will follow the link.
Needs to be set before org.el is loaded."
:group 'org-link-follow
:type 'boolean)
-(defcustom org-mouse-1-follows-link t
+(defcustom org-mouse-1-follows-link
+ (if (boundp 'mouse-1-click-follows-link) mouse-1-click-follows-link t)
"Non-nil means, mouse-1 on a link will follow the link.
-A longer mouse click will still set point. Does not wortk on XEmacs.
+A longer mouse click will still set point. Does not work on XEmacs.
Needs to be set before org.el is loaded."
:group 'org-link-follow
:type 'boolean)
(defcustom org-confirm-shell-link-function 'yes-or-no-p
"Non-nil means, ask for confirmation before executing shell links.
-Shell links can be dangerous, just thing about a link
+Shell links can be dangerous: just think about a link
[[shell:rm -rf ~/*][Google Search]]
-This link would show up in your Org-mode document as \"Google Search\"
+This link would show up in your Org-mode document as \"Google Search\",
but really it would remove your entire home directory.
-Therefore I *definitely* advise against setting this variable to nil.
-Just change it to `y-or-n-p' of you want to confirm with a single key press
-rather than having to type \"yes\"."
+Therefore we advise against setting this variable to nil.
+Just change it to `y-or-n-p' of you want to confirm with a
+single keystroke rather than having to type \"yes\"."
:group 'org-link-follow
:type '(choice
(const :tag "with yes-or-no (safer)" yes-or-no-p)
(const :tag "no confirmation (dangerous)" nil)))
(defcustom org-confirm-elisp-link-function 'yes-or-no-p
- "Non-nil means, ask for confirmation before executing elisp links.
-Elisp links can be dangerous, just think about a link
+ "Non-nil means, ask for confirmation before executing Emacs Lisp links.
+Elisp links can be dangerous: just think about a link
[[elisp:(shell-command \"rm -rf ~/*\")][Google Search]]
-This link would show up in your Org-mode document as \"Google Search\"
+This link would show up in your Org-mode document as \"Google Search\",
but really it would remove your entire home directory.
-Therefore I *definitely* advise against setting this variable to nil.
-Just change it to `y-or-n-p' of you want to confirm with a single key press
-rather than having to type \"yes\"."
+Therefore we advise against setting this variable to nil.
+Just change it to `y-or-n-p' of you want to confirm with a
+single keystroke rather than having to type \"yes\"."
:group 'org-link-follow
:type '(choice
(const :tag "with yes-or-no (safer)" yes-or-no-p)
(const :tag "Default from remember-data-file" nil)
file))
+(defcustom org-remember-store-without-prompt t
+ "Non-nil means, `C-c C-c' stores remember note without further promts.
+In this case, you need `C-u C-c C-c' to get the prompts for
+note file and headline.
+When this variable is nil, `C-c C-c' give you the prompts, and
+`C-u C-c C-c' trigger the fasttrack."
+ :group 'org-remember
+ :type 'boolean)
+
+(defcustom org-remember-interactive-interface 'refile
+ "The interface to be used for interactive filing of remember notes.
+This is only used when the interactive mode for selecting a filing
+location is used (see the variable `org-remember-store-without-prompt').
+Allowed vaues are:
+outline The interface shows an outline of the relevant file
+ and the correct heading is found by moving through
+ the outline or by searching with incremental search.
+outline-path-completion Headlines in the current buffer are offered via
+ completion.
+refile Use the refile interface, and offer headlines,
+ possibly from different buffers."
+ :group 'org-remember
+ :type '(choice
+ (const :tag "Refile" refile)
+ (const :tag "Outline" outline)
+ (const :tag "Outline-path-completion" outline-path-completion)))
+
+(defcustom org-goto-interface 'outline
+ "The default interface to be used for `org-goto'.
+Allowed vaues are:
+outline The interface shows an outline of the relevant file
+ and the correct heading is found by moving through
+ the outline or by searching with incremental search.
+outline-path-completion Headlines in the current buffer are offered via
+ completion."
+ :group 'org-remember ; FIXME: different group for org-goto and org-refile
+ :type '(choice
+ (const :tag "Outline" outline)
+ (const :tag "Outline-path-completion" outline-path-completion)))
+
(defcustom org-remember-default-headline ""
"The headline that should be the default location in the notes file.
When filing remember notes, the cursor will start at that position.
(defcustom org-remember-templates nil
"Templates for the creation of remember buffers.
When nil, just let remember make the buffer.
-When not nil, this is a list of 4-element lists. In each entry, the first
-element is a character, a unique key to select this template.
-The second element is the template. The third element is optional and can
+When not nil, this is a list of 5-element lists. In each entry, the first
+element is the name of the template, which should be a single short word.
+The second element is a character, a unique key to select this template.
+The third element is the template. The fourth element is optional and can
specify a destination file for remember items created with this template.
-The default file is given by `org-default-notes-file'. An optional third
+The default file is given by `org-default-notes-file'. An optional fifth
element can specify the headline in that file that should be offered
first when the user is asked to file the entry. The default headline is
given in the variable `org-remember-default-headline'.
+An optional sixth element specifies the contexts in which the user can
+select the template. This element can be either a list of major modes
+or a function. `org-remember' will first check whether the function
+returns `t' or if we are in any of the listed major modes, and select
+the template accordingly.
+
The template specifies the structure of the remember buffer. It should have
a first line starting with a star, to act as the org-mode headline.
Furthermore, the following %-escapes will be replaced with content:
- %^{prompt} prompt the user for a string and replace this sequence with it.
+ %^{prompt} Prompt the user for a string and replace this sequence with it.
+ A default value and a completion table ca be specified like this:
+ %^{prompt|default|completion2|completion3|...}
%t time stamp, date only
%T time stamp with date and time
%u, %U like the above, but inactive time stamps
You may define a prompt like %^{Please specify birthday}t
%n user name (taken from `user-full-name')
%a annotation, normally the link created with org-store-link
- %i initial content, the region when remember is called with C-u.
- If %i is indented, the entire inserted text will be indented
- as well.
+ %i initial content, the region active. If %i is indented,
+ the entire inserted text will be indented as well.
+ %c content of the clipboard, or current kill ring head
+ %^g prompt for tags, with completion on tags in target file
+ %^G prompt for tags, with completion all tags in all agenda files
+ %:keyword specific information for certain link types, see below
+ %[pathname] insert the contents of the file given by `pathname'
+ %(sexp) evaluate elisp `(sexp)' and replace with the result
+ %! Store this note immediately after filling the template
%? After completing the template, position cursor here.
info | %:type %:file %:node
calendar | %:type %:date"
:group 'org-remember
- :get (lambda (var) ; Make sure all entries have 4 elements
+ :get (lambda (var) ; Make sure all entries have at least 5 elements
(mapcar (lambda (x)
- (cond ((= (length x) 3) (append x '("")))
- ((= (length x) 2) (append x '("" "")))
+ (if (not (stringp (car x))) (setq x (cons "" x)))
+ (cond ((= (length x) 4) (append x '("")))
+ ((= (length x) 3) (append x '("" "")))
(t x)))
(default-value var)))
:type '(repeat
:tag "enabled"
- (list :value (?a "\n" nil nil)
+ (list :value ("" ?a "\n" nil nil nil)
+ (string :tag "Name")
(character :tag "Selection Key")
(string :tag "Template")
- (file :tag "Destination file (optional)")
- (string :tag "Destination headline (optional)"))))
+ (choice
+ (file :tag "Destination file")
+ (const :tag "Prompt for file" nil))
+ (choice
+ (string :tag "Destination headline")
+ (const :tag "Selection interface for heading"))
+ (choice
+ (const :tag "Use by default" nil)
+ (const :tag "Use in all contexts" t)
+ (repeat :tag "Use only if in major mode"
+ (symbol :tag "Major mode"))
+ (function :tag "Perform a check against function")))))
(defcustom org-reverse-note-order nil
"Non-nil means, store new notes at the beginning of a file or entry.
-When nil, new notes will be filed to the end of a file or entry."
+When nil, new notes will be filed to the end of a file or entry.
+This can also be a list with cons cells of regular expressions that
+are matched against file names, and values."
:group 'org-remember
:type '(choice
(const :tag "Reverse always" t)
(repeat :tag "By file name regexp"
(cons regexp boolean))))
+(defcustom org-refile-targets nil
+ "Targets for refiling entries with \\[org-refile].
+This is list of cons cells. Each cell contains:
+- a specification of the files to be considered, either a list of files,
+ or a symbol whose function or value fields will be used to retrieve
+ a file name or a list of file names. Nil means, refile to a different
+ heading in the current buffer.
+- A specification of how to find candidate refile targets. This may be
+ any of
+ - a cons cell (:tag . \"TAG\") to identify refile targets by a tag.
+ This tag has to be present in all target headlines, inheritance will
+ not be considered.
+ - a cons cell (:todo . \"KEYWORD\") to identify refile targets by
+ todo keyword.
+ - a cons cell (:regexp . \"REGEXP\") with a regular expression matching
+ headlines that are refiling targets.
+ - a cons cell (:level . N). Any headline of level N is considered a target.
+ - a cons cell (:maxlevel . N). Any headline with level <= N is a target."
+;; FIXME: what if there are a var and func with same name???
+ :group 'org-remember
+ :type '(repeat
+ (cons
+ (choice :value org-agenda-files
+ (const :tag "All agenda files" org-agenda-files)
+ (const :tag "Current buffer" nil)
+ (function) (variable) (file))
+ (choice :tag "Identify target headline by"
+ (cons :tag "Specific tag" (const :tag) (string))
+ (cons :tag "TODO keyword" (const :todo) (string))
+ (cons :tag "Regular expression" (const :regexp) (regexp))
+ (cons :tag "Level number" (const :level) (integer))
+ (cons :tag "Max Level number" (const :maxlevel) (integer))))))
+
+(defcustom org-refile-use-outline-path nil
+ "Non-nil means, provide refile targets as paths.
+So a level 3 headline will be available as level1/level2/level3.
+When the value is `file', also include the file name (without directory)
+into the path. When `full-file-path', include the full file path."
+ :group 'org-remember
+ :type '(choice
+ (const :tag "Not" nil)
+ (const :tag "Yes" t)
+ (const :tag "Start with file name" file)
+ (const :tag "Start with full file path" full-file-path)))
+
(defgroup org-todo nil
"Options concerning TODO items in Org-mode."
:tag "Org TODO"
:tag "Org Progress"
:group 'org-time)
-(defcustom org-todo-keywords '("TODO" "DONE")
- "List of TODO entry keywords.
-\\<org-mode-map>By default, this is '(\"TODO\" \"DONE\"). The last entry in the list is
-considered to mean that the entry is \"done\". All the other mean that
-action is required, and will make the entry show up in todo lists, diaries
-etc.
-The command \\[org-todo] cycles an entry through these states, and an
+(defcustom org-todo-keywords '((sequence "TODO" "DONE"))
+ "List of TODO entry keyword sequences and their interpretation.
+\\<org-mode-map>This is a list of sequences.
+
+Each sequence starts with a symbol, either `sequence' or `type',
+indicating if the keywords should be interpreted as a sequence of
+action steps, or as different types of TODO items. The first
+keywords are states requiring action - these states will select a headline
+for inclusion into the global TODO list Org-mode produces. If one of
+the \"keywords\" is the vertical bat \"|\" the remaining keywords
+signify that no further action is necessary. If \"|\" is not found,
+the last keyword is treated as the only DONE state of the sequence.
+
+The command \\[org-todo] cycles an entry through these states, and one
additional state where no keyword is present. For details about this
-cycling, see also the variable `org-todo-interpretation'
-Changes become only effective after restarting Emacs."
+cycling, see the manual.
+
+TODO keywords and interpretation can also be set on a per-file basis with
+the special #+SEQ_TODO and #+TYP_TODO lines.
+
+Each keyword can optionally specify a character for fast state selection
+\(in combination with the variable `org-use-fast-todo-selection')
+and specifiers for state change logging, using the same syntax
+that is used in the \"#+TODO:\" lines. For example, \"WAIT(w)\" says
+that the WAIT state can be selected with the \"w\" key. \"WAIT(w!)\"
+indicates to record a time stamp each time this state is selected.
+
+Each keyword may also specify if a timestamp or a note should be
+recorded when entering or leaving the state, by adding additional
+characters in the parenthesis after the keyword. This looks like this:
+\"WAIT(w@/!)\". \"@\" means to add a note (with time), \"!\" means to
+record only the time of the state change. With X and Y being either
+\"@\" or \"!\", \"X/Y\" means use X when entering the state, and use
+Y when leaving the state if and only if the *target* state does not
+define X. You may omit any of the fast-selection key or X or /Y,
+so WAIT(w@), WAIT(w/@) and WAIT(@/@) are all valid.
+
+For backward compatibility, this variable may also be just a list
+of keywords - in this case the interptetation (sequence or type) will be
+taken from the (otherwise obsolete) variable `org-todo-interpretation'."
:group 'org-todo
:group 'org-keywords
- :type '(repeat (string :tag "Keyword")))
+ :type '(choice
+ (repeat :tag "Old syntax, just keywords"
+ (string :tag "Keyword"))
+ (repeat :tag "New syntax"
+ (cons
+ (choice
+ :tag "Interpretation"
+ (const :tag "Sequence (cycling hits every state)" sequence)
+ (const :tag "Type (cycling directly to DONE)" type))
+ (repeat
+ (string :tag "Keyword"))))))
+
+(defvar org-todo-keywords-1 nil
+ "All TODO and DONE keywords active in a buffer.")
+(make-variable-buffer-local 'org-todo-keywords-1)
+(defvar org-todo-keywords-for-agenda nil)
+(defvar org-done-keywords-for-agenda nil)
+(defvar org-not-done-keywords nil)
+(make-variable-buffer-local 'org-not-done-keywords)
+(defvar org-done-keywords nil)
+(make-variable-buffer-local 'org-done-keywords)
+(defvar org-todo-heads nil)
+(make-variable-buffer-local 'org-todo-heads)
+(defvar org-todo-sets nil)
+(make-variable-buffer-local 'org-todo-sets)
+(defvar org-todo-log-states nil)
+(make-variable-buffer-local 'org-todo-log-states)
+(defvar org-todo-kwd-alist nil)
+(make-variable-buffer-local 'org-todo-kwd-alist)
+(defvar org-todo-key-alist nil)
+(make-variable-buffer-local 'org-todo-key-alist)
+(defvar org-todo-key-trigger nil)
+(make-variable-buffer-local 'org-todo-key-trigger)
(defcustom org-todo-interpretation 'sequence
"Controls how TODO keywords are interpreted.
-This variable is only relevant if `org-todo-keywords' contains more than two
-states. \\<org-mode-map>Possible values are `sequence' and `type'.
-
-When `sequence', \\[org-todo] will always switch to the next state in the
-`org-todo-keywords' list. When `type', \\[org-todo] only cycles from state
-to state when executed several times in direct succession. Otherwise, it
-switches directly to DONE from any state.
-See the manual for more information."
+This variable is in principle obsolete and is only used for
+backward compatibility, if the interpretation of todo keywords is
+not given already in `org-todo-keywords'. See that variable for
+more information."
:group 'org-todo
:group 'org-keywords
:type '(choice (const sequence)
(const type)))
+(defcustom org-use-fast-todo-selection 'prefix
+ "Non-nil means, use the fast todo selection scheme with C-c C-t.
+This variable describes if and under what circumstances the cycling
+mechanism for TODO keywords will be replaced by a single-key, direct
+selection scheme.
+
+When nil, fast selection is never used.
+
+When the symbol `prefix', it will be used when `org-todo' is called with
+a prefix argument, i.e. `C-u C-c C-t' in an Org-mode buffer, and `C-u t'
+in an agenda buffer.
+
+When t, fast selection is used by default. In this case, the prefix
+argument forces cycling instead.
+
+In all cases, the special interface is only used if access keys have actually
+been assigned by the user, i.e. if keywords in the configuration are followed
+by a letter in parenthesis, like TODO(t)."
+ :group 'org-todo
+ :type '(choice
+ (const :tag "Never" nil)
+ (const :tag "By default" t)
+ (const :tag "Only with C-u C-c C-t" prefix)))
+
(defcustom org-after-todo-state-change-hook nil
"Hook which is run after the state of a TODO item was changed.
The new state (a string with a TODO keyword, or nil) is available in the
:type 'hook)
(defcustom org-log-done nil
- "When set, insert a (non-active) time stamp when TODO entry is marked DONE.
-When the state of an entry is changed from nothing to TODO, remove a previous
-closing date.
-
-This can also be a list of symbols indicating under which conditions
-the time stamp recording the action should be annotated with a short note.
-Valid members of this list are
-
- done Offer to record a note when marking entries done
- state Offer to record a note whenever changing the TODO state
- of an item. This is only relevant if TODO keywords are
- interpreted as sequence, see variable `org-todo-interpretation'.
- When `state' is set, this includes tracking `done'.
- clock-out Offer to record a note when clocking out of an item.
-
-A separate window will then pop up and allow you to type a note.
-After finishing with C-c C-c, the note will be added directly after the
-timestamp, as a plain list item. See also the variable
-`org-log-note-headings'.
-
-Logging can also be configured on a per-file basis by adding one of
+ "Non-nil means, record a CLOSED timestamp when moving an entry to DONE.
+When equal to the list (done), also prompt for a closing note.
+This can also be configured on a per-file basis by adding one of
the following lines anywhere in the buffer:
#+STARTUP: logdone
- #+STARTUP: nologging
#+STARTUP: lognotedone
- #+STARTUP: lognotestate
- #+STARTUP: lognoteclock-out"
+ #+STARTUP: nologdone"
:group 'org-todo
:group 'org-progress
:type '(choice
- (const :tag "off" nil)
- (const :tag "on" t)
- (set :tag "on, with notes, detailed control" :greedy t :value (done)
- (const :tag "when item is marked DONE" done)
- (const :tag "when TODO state changes" state)
- (const :tag "when clocking out" clock-out))))
+ (const :tag "No logging" nil)
+ (const :tag "Record CLOSED timestamp" time)
+ (const :tag "Record CLOSED timestamp with closing note." note)))
+
+;; Normalize old uses of org-log-done.
+(cond
+ ((eq org-log-done t) (setq org-log-done 'time))
+ ((and (listp org-log-done) (memq 'done org-log-done))
+ (setq org-log-done 'note)))
+
+;; FIXME: document
+(defcustom org-log-note-clock-out nil
+ "Non-nil means, recored a note when clocking out of an item.
+This can also be configured on a per-file basis by adding one of
+the following lines anywhere in the buffer:
+
+ #+STARTUP: lognoteclock-out
+ #+STARTUP: nolognoteclock-out"
+ :group 'org-todo
+ :group 'org-progress
+ :type 'boolean)
+
+(defcustom org-log-done-with-time t
+ "Non-nil means, the CLOSED time stamp will contain date and time.
+When nil, only the date will be recorded."
+ :group 'org-progress
+ :type 'boolean)
(defcustom org-log-note-headings
'((done . "CLOSING NOTE %t")
(state . "State %-12s %t")
(clock-out . ""))
"Headings for notes added when clocking out or closing TODO items.
-The value is an alist, with the car being a sympol indicating the note
+The value is an alist, with the car being a symbol indicating the note
context, and the cdr is the heading to be used. The heading may also be the
empty string.
%t in the heading will be replaced by a time stamp.
state) string)
(cons (const :tag "Heading when clocking out" clock-out) string)))
-(defcustom org-allow-auto-repeat t
- "Non-nil means, find REPEAT cookies in entries and apply them.
-A repeat cookie looks like REPEAT(+1m) and causes deadlines and schedules
-to repeat themselves shifted by a certain amount of time, each time an
-entry is marked DONE."
+(defcustom org-log-states-order-reversed t
+ "Non-nil means, the latest state change note will be directly after heading.
+When nil, the notes will be orderer according to time."
+ :group 'org-todo
+ :group 'org-progress
+ :type 'boolean)
+
+(defcustom org-log-repeat 'time
+ "Non-nil means, record moving through the DONE state when triggering repeat.
+An auto-repeating tasks is immediately switched back to TODO when marked
+done. If you are not logging state changes (by adding \"@\" or \"!\" to
+the TODO keyword definition, or recording a cloing note by setting
+`org-log-done', there will be no record of the task moving trhough DONE.
+This variable forces taking a note anyway. Possible values are:
+
+nil Don't force a record
+time Record a time stamp
+note Record a note
+
+This option can also be set with on a per-file-basis with
+
+ #+STARTUP: logrepeat
+ #+STARTUP: lognoterepeat
+ #+STARTUP: nologrepeat
+
+You can have local logging settings for a subtree by setting the LOGGING
+property to one or more of these keywords."
+ :group 'org-todo
+ :group 'org-progress
+ :type '(choice
+ (const :tag "Don't force a record" nil)
+ (const :tag "Force recording the DONE state" time)
+ (const :tag "Force recording a note with the DONE state" note)))
+
+(defcustom org-clock-into-drawer 2
+ "Should clocking info be wrapped into a drawer?
+When t, clocking info will always be inserted into a :CLOCK: drawer.
+If necessary, the drawer will be created.
+When nil, the drawer will not be created, but used when present.
+When an integer and the number of clocking entries in an item
+reaches or exceeds this number, a drawer will be created."
:group 'org-todo
+ :group 'org-progress
+ :type '(choice
+ (const :tag "Always" t)
+ (const :tag "Only when drawer exists" nil)
+ (integer :tag "When at least N clock entries")))
+
+(defcustom org-clock-out-when-done t
+ "When t, the clock will be stopped when the relevant entry is marked DONE.
+Nil means, clock will keep running until stopped explicitly with
+`C-c C-x C-o', or until the clock is started in a different item."
:group 'org-progress
:type 'boolean)
+(defcustom org-clock-in-switch-to-state nil
+ "Set task to a special todo state while clocking it.
+The value should be the state to which the entry should be switched."
+ :group 'org-progress
+ :group 'org-todo
+ :type '(choice
+ (const :tag "Don't force a state" nil)
+ (string :tag "State")))
+
(defgroup org-priorities nil
"Priorities in Org-mode."
:tag "Org Priorities"
:group 'org-todo)
+(defcustom org-highest-priority ?A
+ "The highest priority of TODO items. A character like ?A, ?B etc.
+Must have a smaller ASCII number than `org-lowest-priority'."
+ :group 'org-priorities
+ :type 'character)
+
+(defcustom org-lowest-priority ?C
+ "The lowest priority of TODO items. A character like ?A, ?B etc.
+Must have a larger ASCII number than `org-highest-priority'."
+ :group 'org-priorities
+ :type 'character)
+
(defcustom org-default-priority ?B
"The default priority of TODO items.
This is the priority an item get if no explicit priority is given."
:group 'org-priorities
:type 'character)
-(defcustom org-lowest-priority ?C
- "The lowest priority of TODO items. A character like ?A, ?B etc."
+(defcustom org-priority-start-cycle-with-default t
+ "Non-nil means, start with default priority when starting to cycle.
+When this is nil, the first step in the cycle will be (depending on the
+command used) one higher or lower that the default priority."
:group 'org-priorities
- :type 'character)
+ :type 'boolean)
(defgroup org-time nil
"Options concerning time stamps and deadlines in Org-mode."
"Formats for `format-time-string' which are used for time stamps.
It is not recommended to change this constant.")
-(defcustom org-time-stamp-rounding-minutes 0
- "Number of minutes to round time stamps to upon insertion.
-When zero, insert the time unmodified. Useful rounding numbers
-should be factors of 60, so for example 5, 10, 15.
-When this is not zero, you can still force an exact time-stamp by using
-a double prefix argument to a time-stamp command like `C-c .' or `C-c !'."
+(defcustom org-time-stamp-rounding-minutes '(0 5)
+ "Number of minutes to round time stamps to.
+These are two values, the first applies when first creating a time stamp.
+The second applies when changing it with the commands `S-up' and `S-down'.
+When changing the time stamp, this means that it will change in steps
+of N minutes, as given by the second value.
+
+When a setting is 0 or 1, insert the time unmodified. Useful rounding
+numbers should be factors of 60, so for example 5, 10, 15.
+
+When this is larger than 1, you can still force an exact time-stamp by using
+a double prefix argument to a time-stamp command like `C-c .' or `C-c !',
+and by using a prefix arg to `S-up/down' to specify the exact number
+of minutes to shift."
:group 'org-time
- :type 'integer)
+ :get '(lambda (var) ; Make sure all entries have 5 elements
+ (if (integerp (default-value var))
+ (list (default-value var) 5)
+ (default-value var)))
+ :type '(list
+ (integer :tag "when inserting times")
+ (integer :tag "when modifying times")))
+
+;; Make sure old customizations of this variable don't lead to problems.
+(when (integerp org-time-stamp-rounding-minutes)
+ (setq org-time-stamp-rounding-minutes
+ (list org-time-stamp-rounding-minutes
+ org-time-stamp-rounding-minutes)))
(defcustom org-display-custom-times nil
"Non-nil means, overlay custom formats over all time stamps.
'("<%m/%d/%y %a>" . "<%m/%d/%y %a %H:%M>") ; american
"Custom formats for time stamps. See `format-time-string' for the syntax.
These are overlayed over the default ISO format if the variable
-`org-display-custom-times' is set."
+`org-display-custom-times' is set. Time like %H:%M should be at the
+end of the second format."
:group 'org-time
:type 'sexp)
(concat "[" (substring f 1 -1) "]")
f)))
-(defcustom org-deadline-warning-days 30
- "No. of days before expiration during which a deadline becomes active.
-This variable governs the display in sparse trees and in the agenda."
+(defcustom org-read-date-prefer-future t
+ "Non-nil means, assume future for incomplete date input from user.
+This affects the following situations:
+1. The user gives a day, but no month.
+ For example, if today is the 15th, and you enter \"3\", Org-mode will
+ read this as the third of *next* month. However, if you enter \"17\",
+ it will be considered as *this* month.
+2. The user gives a month but not a year.
+ For example, if it is april and you enter \"feb 2\", this will be read
+ as feb 2, *next* year. \"May 5\", however, will be this year.
+
+When this option is nil, the current month and year will always be used
+as defaults."
:group 'org-time
- :type 'number)
+ :type 'boolean)
-(defcustom org-popup-calendar-for-date-prompt t
+(defcustom org-read-date-display-live t
+ "Non-nil means, display current interpretation of date prompt live.
+This display will be in an overlay, in the minibuffer."
+ :group 'org-time
+ :type 'boolean)
+
+(defcustom org-read-date-popup-calendar t
"Non-nil means, pop up a calendar when prompting for a date.
In the calendar, the date can be selected with mouse-1. However, the
minibuffer will also be active, and you can simply enter the date as well.
When nil, only the minibuffer will be available."
:group 'org-time
:type 'boolean)
+(if (fboundp 'defvaralias)
+ (defvaralias 'org-popup-calendar-for-date-prompt
+ 'org-read-date-popup-calendar))
+
+(defcustom org-extend-today-until 0
+ "The hour when your day really ends.
+This has influence for the following applications:
+- When switching the agenda to \"today\". It it is still earlier than
+ the time given here, the day recognized as TODAY is actually yesterday.
+- When a date is read from the user and it is still before the time given
+ here, the current date and time will be assumed to be yesterday, 23:59.
+
+FIXME:
+IMPORTANT: This is still a very experimental feature, it may disappear
+again or it may be extended to mean more things."
+ :group 'org-time
+ :type 'number)
+
+(defcustom org-edit-timestamp-down-means-later nil
+ "Non-nil means, S-down will increase the time in a time stamp.
+When nil, S-up will increase."
+ :group 'org-time
+ :type 'boolean)
(defcustom org-calendar-follow-timestamp-change t
"Non-nil means, make the calendar window follow timestamp changes.
:group 'org-time
:type 'boolean)
+(defcustom org-clock-heading-function nil
+ "When non-nil, should be a function to create `org-clock-heading'.
+This is the string shown in the mode line when a clock is running.
+The function is called with point at the beginning of the headline."
+ :group 'org-time ; FIXME: Should we have a separate group????
+ :type 'function)
+
(defgroup org-tags nil
"Options concerning tags in Org-mode."
:tag "Org Tags"
"List of tags allowed in Org-mode files.
When this list is nil, Org-mode will base TAG input on what is already in the
buffer.
-The value of this variable is an alist, the car may be (and should) be a
-character that is used to select that tag through the fast-tag-selection
-interface. See the manual for details."
+The value of this variable is an alist, the car of each entry must be a
+keyword as a string, the cdr may be a character that is used to select
+that tag through the fast-tag-selection interface.
+See the manual for details."
:group 'org-tags
:type '(repeat
(choice
(const :tag "Yes" t)
(const :tag "Expert" expert)))
-(defcustom org-tags-column 48
+(defvar org-fast-tag-selection-include-todo nil
+ "Non-nil means, fast tags selection interface will also offer TODO states.
+This is an undocumented feature, you should not rely on it.")
+
+(defcustom org-tags-column -80
"The column to which tags should be indented in a headline.
If this number is positive, it specifies the column. If it is negative,
it means that the tags should be flushright to that column. For example,
--79 works well for a normal 80 character screen."
+-80 works well for a normal 80 character screen."
:group 'org-tags
:type 'integer)
"History of minibuffer reads for tags.")
(defvar org-last-tags-completion-table nil
"The last used completion table for tags.")
+(defvar org-after-tags-change-hook nil
+ "Hook that is run after the tags in a line have changed.")
+
+(defgroup org-properties nil
+ "Options concerning properties in Org-mode."
+ :tag "Org Properties"
+ :group 'org)
+
+(defcustom org-property-format "%-10s %s"
+ "How property key/value pairs should be formatted by `indent-line'.
+When `indent-line' hits a property definition, it will format the line
+according to this format, mainly to make sure that the values are
+lined-up with respect to each other."
+ :group 'org-properties
+ :type 'string)
+
+(defcustom org-use-property-inheritance nil
+ "Non-nil means, properties apply also for sublevels.
+This setting is only relevant during property searches, not when querying
+an entry with `org-entry-get'. To retrieve a property with inheritance,
+you need to call `org-entry-get' with the inheritance flag.
+Turning this on can cause significant overhead when doing a search, so
+this is turned off by default.
+When nil, only the properties directly given in the current entry count.
+The value may also be a list of properties that shouldhave inheritance.
+
+However, note that some special properties use inheritance under special
+circumstances (not in searches). Examples are CATEGORY, ARCHIVE, COLUMNS,
+and the properties ending in \"_ALL\" when they are used as descriptor
+for valid values of a property."
+ :group 'org-properties
+ :type '(choice
+ (const :tag "Not" nil)
+ (const :tag "Always" nil)
+ (repeat :tag "Specific properties" (string :tag "Property"))))
+
+(defcustom org-columns-default-format "%25ITEM %TODO %3PRIORITY %TAGS"
+ "The default column format, if no other format has been defined.
+This variable can be set on the per-file basis by inserting a line
+
+#+COLUMNS: %25ITEM ....."
+ :group 'org-properties
+ :type 'string)
+
+(defcustom org-global-properties nil
+ "List of property/value pairs that can be inherited by any entry.
+You can set buffer-local values for this by adding lines like
+
+#+PROPERTY: NAME VALUE"
+ :group 'org-properties
+ :type '(repeat
+ (cons (string :tag "Property")
+ (string :tag "Value"))))
+
+(defvar org-local-properties nil
+ "List of property/value pairs that can be inherited by any entry.
+Valid for the current buffer.
+This variable is populated from #+PROPERTY lines.")
(defgroup org-agenda nil
"Options concerning agenda views in Org-mode."
"Variable used by org files to set a category for agenda display.
Such files should use a file variable to set it, for example
- -*- mode: org; org-category: \"ELisp\"
+# -*- mode: org; org-category: \"ELisp\"
or contain a special line
Entries may be added to this list with \\[org-agenda-file-to-front] and removed with
\\[org-remove-file]. You can also use customize to edit the list.
+If an entry is a directory, all files in that directory that are matched by
+`org-agenda-file-regexp' will be part of the file list.
+
If the value of the variable is not a list but a single file name, then
the list of agenda files is actually stored and maintained in that file, one
agenda file per line."
:group 'org-agenda
:type '(choice
- (repeat :tag "List of files" file)
+ (repeat :tag "List of files and directories" file)
(file :tag "Store list in a file\n" :value "~/.agenda_files")))
+(defcustom org-agenda-file-regexp "\\`[^.].*\\.org\\'"
+ "Regular expression to match files for `org-agenda-files'.
+If any element in the list in that variable contains a directory instead
+of a normal file, all files in that directory that are matched by this
+regular expression will be included."
+ :group 'org-agenda
+ :type 'regexp)
+
+(defcustom org-agenda-skip-unavailable-files nil
+ "t means to just skip non-reachable files in `org-agenda-files'.
+Nil means to remove them, after a query, from the list."
+ :group 'org-agenda
+ :type 'boolean)
+
+(defcustom org-agenda-text-search-extra-files nil
+ "List of extra files to be searched by text search commands.
+These files will be search in addition to the agenda files bu the
+commands `org-search-view' (`C-c a s') and `org-occur-in-agenda-files'.
+Note that these files will only be searched for text search commands,
+not for the other agenda views like todo lists, tag earches or the weekly
+agenda. This variable is intended to list notes and possibly archive files
+that should also be searched by these two commands."
+ :group 'org-agenda
+ :type '(repeat file))
+
+(if (fboundp 'defvaralias)
+ (defvaralias 'org-agenda-multi-occur-extra-files
+ 'org-agenda-text-search-extra-files))
(defcustom org-agenda-confirm-kill 1
"When set, remote killing from the agenda buffer needs confirmation.
:group 'org-agenda
:type 'sexp)
+(defcustom org-agenda-compact-blocks nil
+ "Non-nil means, make the block agenda more compact.
+This is done by leaving out unnecessary lines."
+ :group 'org-agenda
+ :type nil)
+
+(defgroup org-agenda-export nil
+ "Options concerning exporting agenda views in Org-mode."
+ :tag "Org Agenda Export"
+ :group 'org-agenda)
+
+(defcustom org-agenda-with-colors t
+ "Non-nil means, use colors in agenda views."
+ :group 'org-agenda-export
+ :type 'boolean)
+
+(defcustom org-agenda-exporter-settings nil
+ "Alist of variable/value pairs that should be active during agenda export.
+This is a good place to set uptions for ps-print and for htmlize."
+ :group 'org-agenda-export
+ :type '(repeat
+ (list
+ (variable)
+ (sexp :tag "Value"))))
+
+(defcustom org-agenda-export-html-style ""
+ "The style specification for exported HTML Agenda files.
+If this variable contains a string, it will replace the default <style>
+section as produced by `htmlize'.
+Since there are different ways of setting style information, this variable
+needs to contain the full HTML structure to provide a style, including the
+surrounding HTML tags. The style specifications should include definitions
+the fonts used by the agenda, here is an example:
+
+ <style type=\"text/css\">
+ p { font-weight: normal; color: gray; }
+ .org-agenda-structure {
+ font-size: 110%;
+ color: #003399;
+ font-weight: 600;
+ }
+ .org-todo {
+ color: #cc6666;
+ font-weight: bold;
+ }
+ .org-done {
+ color: #339933;
+ }
+ .title { text-align: center; }
+ .todo, .deadline { color: red; }
+ .done { color: green; }
+ </style>
+
+or, if you want to keep the style in a file,
+
+ <link rel=\"stylesheet\" type=\"text/css\" href=\"mystyles.css\">
+
+As the value of this option simply gets inserted into the HTML <head> header,
+you can \"misuse\" it to also add other text to the header. However,
+<style>...</style> is required, if not present the variable will be ignored."
+ :group 'org-agenda-export
+ :group 'org-export-html
+ :type 'string)
+
(defgroup org-agenda-custom-commands nil
"Options concerning agenda views in Org-mode."
:tag "Org Agenda Custom Commands"
:group 'org-agenda)
-(defcustom org-agenda-custom-commands '(("w" todo "WAITING"))
+(defconst org-sorting-choice
+ '(choice
+ (const time-up) (const time-down)
+ (const category-keep) (const category-up) (const category-down)
+ (const tag-down) (const tag-up)
+ (const priority-up) (const priority-down))
+ "Sorting choices.")
+
+(defconst org-agenda-custom-commands-local-options
+ `(repeat :tag "Local settings for this command. Remember to quote values"
+ (choice :tag "Setting"
+ (list :tag "Any variable"
+ (variable :tag "Variable")
+ (sexp :tag "Value"))
+ (list :tag "Files to be searched"
+ (const org-agenda-files)
+ (list
+ (const :format "" quote)
+ (repeat
+ (file))))
+ (list :tag "Sorting strategy"
+ (const org-agenda-sorting-strategy)
+ (list
+ (const :format "" quote)
+ (repeat
+ ,org-sorting-choice)))
+ (list :tag "Prefix format"
+ (const org-agenda-prefix-format :value " %-12:c%?-12t% s")
+ (string))
+ (list :tag "Number of days in agenda"
+ (const org-agenda-ndays)
+ (integer :value 1))
+ (list :tag "Fixed starting date"
+ (const org-agenda-start-day)
+ (string :value "2007-11-01"))
+ (list :tag "Start on day of week"
+ (const org-agenda-start-on-weekday)
+ (choice :value 1
+ (const :tag "Today" nil)
+ (number :tag "Weekday No.")))
+ (list :tag "Include data from diary"
+ (const org-agenda-include-diary)
+ (boolean))
+ (list :tag "Deadline Warning days"
+ (const org-deadline-warning-days)
+ (integer :value 1))
+ (list :tag "Standard skipping condition"
+ :value (org-agenda-skip-function '(org-agenda-skip-entry-if))
+ (const org-agenda-skip-function)
+ (list
+ (const :format "" quote)
+ (list
+ (choice
+ :tag "Skiping range"
+ (const :tag "Skip entry" org-agenda-skip-entry-if)
+ (const :tag "Skip subtree" org-agenda-skip-subtree-if))
+ (repeat :inline t :tag "Conditions for skipping"
+ (choice
+ :tag "Condition type"
+ (list :tag "Regexp matches" :inline t (const :format "" 'regexp) (regexp))
+ (list :tag "Regexp does not match" :inline t (const :format "" 'notregexp) (regexp))
+ (const :tag "scheduled" 'scheduled)
+ (const :tag "not scheduled" 'notscheduled)
+ (const :tag "deadline" 'deadline)
+ (const :tag "no deadline" 'notdeadline))))))
+ (list :tag "Non-standard skipping condition"
+ :value (org-agenda-skip-function)
+ (list
+ (const org-agenda-skip-function)
+ (sexp :tag "Function or form (quoted!)")))))
+ "Selection of examples for agenda command settings.
+This will be spliced into the custom type of
+`org-agenda-custom-commands'.")
+
+
+(defcustom org-agenda-custom-commands nil
"Custom commands for the agenda.
These commands will be offered on the splash screen displayed by the
agenda dispatcher \\[org-agenda]. Each entry is a list like this:
- (key type match options)
-
-key The key (a single char as a string) to be associated with the command.
-type The command type, any of the following symbols:
- todo Entries with a specific TODO keyword, in all agenda files.
- tags Tags match in all agenda files.
- tags-todo Tags match in all agenda files, TODO entries only.
- todo-tree Sparse tree of specific TODO keyword in *current* file.
- tags-tree Sparse tree with all tags matches in *current* file.
- occur-tree Occur sparse tree for *current* file.
-match What to search for:
- - a single keyword for TODO keyword searches
- - a tags match expression for tags searches
- - a regular expression for occur searches
-options A list of option setttings, similar to that in a let form, so like
- this: ((opt1 val1) (opt2 val2) ...)
+ (key desc type match settings files)
+
+key The key (one or more characters as a string) to be associated
+ with the command.
+desc A description of the command, when omitted or nil, a default
+ description is built using MATCH.
+type The command type, any of the following symbols:
+ agenda The daily/weekly agenda.
+ todo Entries with a specific TODO keyword, in all agenda files.
+ search Entries containing search words entry or headline.
+ tags Tags/Property/TODO match in all agenda files.
+ tags-todo Tags/P/T match in all agenda files, TODO entries only.
+ todo-tree Sparse tree of specific TODO keyword in *current* file.
+ tags-tree Sparse tree with all tags matches in *current* file.
+ occur-tree Occur sparse tree for *current* file.
+ ... A user-defined function.
+match What to search for:
+ - a single keyword for TODO keyword searches
+ - a tags match expression for tags searches
+ - a word search expression for text searches.
+ - a regular expression for occur searches
+ For all other commands, this should be the empty string.
+settings A list of option settings, similar to that in a let form, so like
+ this: ((opt1 val1) (opt2 val2) ...). The values will be
+ evaluated at the moment of execution, so quote them when needed.
+files A list of files file to write the produced agenda buffer to
+ with the command `org-store-agenda-views'.
+ If a file name ends in \".html\", an HTML version of the buffer
+ is written out. If it ends in \".ps\", a postscript version is
+ produced. Otherwide, only the plain text is written to the file.
You can also define a set of commands, to create a composite agenda buffer.
In this case, an entry looks like this:
- (key desc (cmd1 cmd2 ...) general-options)
+ (key desc (cmd1 cmd2 ...) general-settings-for-whole-set files)
where
cmd An agenda command, similar to the above. However, tree commands
are no allowed, but instead you can get agenda and global todo list.
So valid commands for a set are:
- (agenda)
- (alltodo)
- (stuck)
- (todo \"match\" options)
- (tags \"match\" options )
- (tags-todo \"match\" options)
+ (agenda \"\" settings)
+ (alltodo \"\" settings)
+ (stuck \"\" settings)
+ (todo \"match\" settings files)
+ (search \"match\" settings files)
+ (tags \"match\" settings files)
+ (tags-todo \"match\" settings files)
Each command can carry a list of options, and another set of options can be
given for the whole set of commands. Individual command options take
-precedence over the general options."
+precedence over the general options.
+
+When using several characters as key to a command, the first characters
+are prefix commands. For the dispatcher to display useful information, you
+should provide a description for the prefix, like
+
+ (setq org-agenda-custom-commands
+ '((\"h\" . \"HOME + Name tag searches\") ; describe prefix \"h\"
+ (\"hl\" tags \"+HOME+Lisa\")
+ (\"hp\" tags \"+HOME+Peter\")
+ (\"hk\" tags \"+HOME+Kim\")))"
:group 'org-agenda-custom-commands
- :type '(repeat
- (choice
+ :type `(repeat
+ (choice :value ("x" "Describe command here" tags "" nil)
(list :tag "Single command"
- (string :tag "Key")
+ (string :tag "Access Key(s) ")
+ (option (string :tag "Description"))
(choice
+ (const :tag "Agenda" agenda)
+ (const :tag "TODO list" alltodo)
+ (const :tag "Search words" search)
+ (const :tag "Stuck projects" stuck)
(const :tag "Tags search (all agenda files)" tags)
(const :tag "Tags search of TODO entries (all agenda files)" tags-todo)
(const :tag "TODO keyword search (all agenda files)" todo)
(const :tag "Tags sparse tree (current buffer)" tags-tree)
(const :tag "TODO keyword tree (current buffer)" todo-tree)
(const :tag "Occur tree (current buffer)" occur-tree)
- (symbol :tag "Other, user-defined function"))
- (string :tag "Match")
- (repeat :tag "Local options"
- (list (variable :tag "Option") (sexp :tag "Value"))))
+ (sexp :tag "Other, user-defined function"))
+ (string :tag "Match (only for some commands)")
+ ,org-agenda-custom-commands-local-options
+ (option (repeat :tag "Export" (file :tag "Export to"))))
(list :tag "Command series, all agenda files"
- (string :tag "Key")
- (string :tag "Description")
- (repeat
+ (string :tag "Access Key(s)")
+ (string :tag "Description ")
+ (repeat :tag "Component"
(choice
- (const :tag "Agenda" (agenda))
- (const :tag "TODO list" (alltodo))
- (const :tag "Stuck projects" (stuck))
+ (list :tag "Agenda"
+ (const :format "" agenda)
+ (const :tag "" :format "" "")
+ ,org-agenda-custom-commands-local-options)
+ (list :tag "TODO list (all keywords)"
+ (const :format "" alltodo)
+ (const :tag "" :format "" "")
+ ,org-agenda-custom-commands-local-options)
+ (list :tag "Search words"
+ (const :format "" search)
+ (string :tag "Match")
+ ,org-agenda-custom-commands-local-options)
+ (list :tag "Stuck projects"
+ (const :format "" stuck)
+ (const :tag "" :format "" "")
+ ,org-agenda-custom-commands-local-options)
(list :tag "Tags search"
(const :format "" tags)
(string :tag "Match")
- (repeat :tag "Local options"
- (list (variable :tag "Option")
- (sexp :tag "Value"))))
-
+ ,org-agenda-custom-commands-local-options)
(list :tag "Tags search, TODO entries only"
(const :format "" tags-todo)
(string :tag "Match")
- (repeat :tag "Local options"
- (list (variable :tag "Option")
- (sexp :tag "Value"))))
-
+ ,org-agenda-custom-commands-local-options)
(list :tag "TODO keyword search"
(const :format "" todo)
(string :tag "Match")
- (repeat :tag "Local options"
- (list (variable :tag "Option")
- (sexp :tag "Value"))))
-
+ ,org-agenda-custom-commands-local-options)
(list :tag "Other, user-defined function"
(symbol :tag "function")
(string :tag "Match")
- (repeat :tag "Local options"
- (list (variable :tag "Option")
- (sexp :tag "Value"))))))
-
- (repeat :tag "General options"
- (list (variable :tag "Option")
- (sexp :tag "Value")))))))
+ ,org-agenda-custom-commands-local-options)))
+
+ (repeat :tag "Settings for entire command set"
+ (list (variable :tag "Any variable")
+ (sexp :tag "Value")))
+ (option (repeat :tag "Export" (file :tag "Export to"))))
+ (cons :tag "Prefix key documentation"
+ (string :tag "Access Key(s)")
+ (string :tag "Description ")))))
+
+(defcustom org-agenda-query-register ?o
+ "The register holding the current query string.
+The prupose of this is that if you construct a query string interactively,
+you can then use it to define a custom command."
+ :group 'org-agenda-custom-commands
+ :type 'character)
(defcustom org-stuck-projects
- '("+LEVEL=2/-DONE" ("TODO" "NEXT" "NEXTACTION") nil)
+ '("+LEVEL=2/-DONE" ("TODO" "NEXT" "NEXTACTION") nil "")
"How to identify stuck projects.
-This is a list of three items:
+This is a list of four items:
1. A tags/todo matcher string that is used to identify a project.
- The entire tree below a headline matched by this is considered a project.
-2. A list of TODO keywords itentifying non-stuck projects.
+ The entire tree below a headline matched by this is considered one project.
+2. A list of TODO keywords identifying non-stuck projects.
If the project subtree contains any headline with one of these todo
- keywords, the project is consitered to be not stuck.
+ keywords, the project is considered to be not stuck. If you specify
+ \"*\" as a keyword, any TODO keyword will mark the project unstuck.
3. A list of tags identifying non-stuck projects.
If the project subtree contains any headline with one of these tags,
- the project is consitered to be not stuck.
+ the project is considered to be not stuck. If you specify \"*\" as
+ a tag, any tag will mark the project unstuck.
+4. An arbitrary regular expression matching non-stuck projects.
After defining this variable, you may use \\[org-agenda-list-stuck-projects]
or `C-c a #' to produce the list."
:type '(list
(string :tag "Tags/TODO match to identify a project")
(repeat :tag "Projects are *not* stuck if they have an entry with TODO keyword any of" (string))
- (repeat :tag "Projects are *not* stuck if they have an entry with TAG being any of" (string))))
+ (repeat :tag "Projects are *not* stuck if they have an entry with TAG being any of" (string))
+ (regexp :tag "Projects are *not* stuck if this regexp matches\ninside the subtree")))
(defgroup org-agenda-skip nil
:group 'org-todo
:type 'boolean)
+(defcustom org-agenda-todo-ignore-with-date nil
+ "Non-nil means, don't show entries with a date in the global todo list.
+You can use this if you prefer to mark mere appointments with a TODO keyword,
+but don't want them to show up in the TODO list.
+When this is set, it also covers deadlines and scheduled items, the settings
+of `org-agenda-todo-ignore-scheduled' and `org-agenda-todo-ignore-deadlines'
+will be ignored."
+ :group 'org-agenda-skip
+ :group 'org-todo
+ :type 'boolean)
+
(defcustom org-agenda-todo-ignore-scheduled nil
"Non-nil means, don't show scheduled entries in the global todo list.
The idea behind this is that by scheduling it, you have already taken care
-of this item."
+of this item.
+See also `org-agenda-todo-ignore-with-date'."
:group 'org-agenda-skip
:group 'org-todo
:type 'boolean)
(defcustom org-agenda-todo-ignore-deadlines nil
"Non-nil means, don't show near deadline entries in the global todo list.
Near means closer than `org-deadline-warning-days' days.
-The idea behind this is that such items will appear in the agenda anyway."
+The idea behind this is that such items will appear in the agenda anyway.
+See also `org-agenda-todo-ignore-with-date'."
:group 'org-agenda-skip
:group 'org-todo
:type 'boolean)
(defcustom org-agenda-skip-scheduled-if-done nil
"Non-nil means don't show scheduled items in agenda when they are done.
-This is relevant for the daily/weekly agenda, not for the TODO list."
+This is relevant for the daily/weekly agenda, not for the TODO list. And
+it applies only to the actual date of the scheduling. Warnings about
+an item with a past scheduling dates are always turned off when the item
+is DONE."
:group 'org-agenda-skip
:type 'boolean)
-(defcustom org-timeline-show-empty-dates 3
- "Non-nil means, `org-timeline' also shows dates without an entry.
-When nil, only the days which actually have entries are shown.
-When t, all days between the first and the last date are shown.
+(defcustom org-agenda-skip-deadline-if-done nil
+ "Non-nil means don't show deadines when the corresponding item is done.
+When nil, the deadline is still shown and should give you a happy feeling.
+This is relevant for the daily/weekly agenda. And it applied only to the
+actualy date of the deadline. Warnings about approching and past-due
+deadlines are always turned off when the item is DONE."
+ :group 'org-agenda-skip
+ :type 'boolean)
+
+(defcustom org-agenda-skip-timestamp-if-done nil
+ "Non-nil means don't select item by timestamp or -range if it is DONE."
+ :group 'org-agenda-skip
+ :type 'boolean)
+
+(defcustom org-timeline-show-empty-dates 3
+ "Non-nil means, `org-timeline' also shows dates without an entry.
+When nil, only the days which actually have entries are shown.
+When t, all days between the first and the last date are shown.
When an integer, show also empty dates, but if there is a gap of more than
N days, just insert a special line indicating the size of the gap."
:group 'org-agenda-skip
(defcustom org-agenda-mouse-1-follows-link nil
"Non-nil means, mouse-1 on a link will follow the link in the agenda.
-A longer mouse click will still set point. Does not wortk on XEmacs.
+A longer mouse click will still set point. Does not work on XEmacs.
Needs to be set before org.el is loaded."
:group 'org-agenda-startup
:type 'boolean)
(defcustom org-agenda-start-with-follow-mode nil
- "The initial value of follwo-mode in a newly created agenda window."
+ "The initial value of follow-mode in a newly created agenda window."
:group 'org-agenda-startup
:type 'boolean)
(const other-window)
(const reorganize-frame)))
+(defcustom org-agenda-window-frame-fractions '(0.5 . 0.75)
+ "The min and max height of the agenda window as a fraction of frame height.
+The value of the variable is a cons cell with two numbers between 0 and 1.
+It only matters if `org-agenda-window-setup' is `reorganize-frame'."
+ :group 'org-agenda-windows
+ :type '(cons (number :tag "Minimum") (number :tag "Maximum")))
+
(defcustom org-agenda-restore-windows-after-quit nil
"Non-nil means, restore window configuration open exiting agenda.
Before the window configuration is changed for displaying the agenda,
current-window Display in the current window
other-window Just display in another window.
dedicated-frame Create one new frame, and re-use it each time.
-new-frame Make a new frame each time."
+new-frame Make a new frame each time. Note that in this case
+ previously-made indirect buffers are kept, and you need to
+ kill these buffers yourself."
:group 'org-structure
:group 'org-agenda-windows
:type '(choice
:group 'org-agenda-daily/weekly
:type 'boolean)
-(defcustom org-agenda-date-format "%A %d %B %Y"
+(defcustom org-agenda-format-date 'org-agenda-format-date-aligned
"Format string for displaying dates in the agenda.
Used by the daily/weekly agenda and by the timeline. This should be
-a format string understood by `format-time-string'.
-FIXME: Not used currently, because of timezone problem."
+a format string understood by `format-time-string', or a function returning
+the formatted date as a string. The function must take a single argument,
+a calendar-style date list like (month day year)."
:group 'org-agenda-daily/weekly
- :type 'string)
+ :type '(choice
+ (string :tag "Format string")
+ (function :tag "Function")))
+
+(defun org-agenda-format-date-aligned (date)
+ "Format a date string for display in the daily/weekly agenda, or timeline.
+This function makes sure that dates are aligned for easy reading."
+ (format "%-9s %2d %s %4d"
+ (calendar-day-name date)
+ (cadr date) ; day
+ (calendar-month-name (car date)) ; month
+ (nth 2 date))) ; year
(defcustom org-agenda-include-diary nil
"If non-nil, include in the agenda entries from the Emacs Calendar's diary."
:group 'org-agenda-daily/weekly
:type 'boolean)
+(defcustom org-agenda-repeating-timestamp-show-all t
+ "Non-nil means, show all occurences of a repeating stamp in the agenda.
+When nil, only one occurence is shown, either today or the
+nearest into the future."
+ :group 'org-agenda-daily/weekly
+ :type 'boolean)
+
+(defcustom org-deadline-warning-days 14
+ "No. of days before expiration during which a deadline becomes active.
+This variable governs the display in sparse trees and in the agenda.
+When 0 or negative, it means use this number (the absolute value of it)
+even if a deadline has a different individual lead time specified."
+ :group 'org-time
+ :group 'org-agenda-daily/weekly
+ :type 'number)
+
+(defcustom org-scheduled-past-days 10000
+ "No. of days to continue listing scheduled items that are not marked DONE.
+When an item is scheduled on a date, it shows up in the agenda on this
+day and will be listed until it is marked done for the number of days
+given here."
+ :group 'org-agenda-daily/weekly
+ :type 'number)
+
(defgroup org-agenda-time-grid nil
"Options concerning the time grid in the Org-mode Agenda."
:tag "Org Agenda Time Grid"
:tag "Org Agenda Sorting"
:group 'org-agenda)
-(let ((sorting-choice
- '(choice
- (const time-up) (const time-down)
- (const category-keep) (const category-up) (const category-down)
- (const tag-down) (const tag-up)
- (const priority-up) (const priority-down))))
-
- (defcustom org-agenda-sorting-strategy
- '((agenda time-up category-keep priority-down)
- (todo category-keep priority-down)
- (tags category-keep))
- "Sorting structure for the agenda items of a single day.
+(defcustom org-agenda-sorting-strategy
+ '((agenda time-up category-keep priority-down)
+ (todo category-keep priority-down)
+ (tags category-keep priority-down)
+ (search category-keep))
+ "Sorting structure for the agenda items of a single day.
This is a list of symbols which will be used in sequence to determine
if an entry should be listed before another entry. The following
symbols are recognized:
priority.
Leaving out `category-keep' would mean that items will be sorted across
-categories by priority."
+categories by priority.
+
+Instead of a single list, this can also be a set of list for specific
+contents, with a context symbol in the car of the list, any of
+`agenda', `todo', `tags' for the corresponding agenda views."
:group 'org-agenda-sorting
:type `(choice
- (repeat :tag "General" ,sorting-choice)
+ (repeat :tag "General" ,org-sorting-choice)
(list :tag "Individually"
(cons (const :tag "Strategy for Weekly/Daily agenda" agenda)
- (repeat ,sorting-choice))
+ (repeat ,org-sorting-choice))
(cons (const :tag "Strategy for TODO lists" todo)
- (repeat ,sorting-choice))
+ (repeat ,org-sorting-choice))
(cons (const :tag "Strategy for Tags matches" tags)
- (repeat ,sorting-choice))))))
+ (repeat ,org-sorting-choice)))))
(defcustom org-sort-agenda-notime-is-late t
"Non-nil means, items without time are considered late.
:group 'org-agenda-sorting
:type 'boolean)
-(defgroup org-agenda-prefix nil
+(defgroup org-agenda-line-format nil
"Options concerning the entry prefix in the Org-mode agenda display."
- :tag "Org Agenda Prefix"
+ :tag "Org Agenda Line Format"
:group 'org-agenda)
(defcustom org-agenda-prefix-format
'((agenda . " %-12:c%?-12t% s")
(timeline . " % s")
(todo . " %-12:c")
- (tags . " %-12:c"))
+ (tags . " %-12:c")
+ (search . " %-12:c"))
"Format specifications for the prefix of items in the agenda views.
An alist with four entries, for the different agenda types. The keys to the
sublists are `agenda', `timeline', `todo', and `tags'. The values
(setq org-agenda-prefix-format \" %-11:c% s\")
See also the variables `org-agenda-remove-times-when-in-prefix' and
-`org-agenda-remove-tags-when-in-prefix'."
+`org-agenda-remove-tags'."
:type '(choice
(string :tag "General format")
(list :greedy t :tag "View dependent"
(cons (const agenda) (string :tag "Format"))
(cons (const timeline) (string :tag "Format"))
(cons (const todo) (string :tag "Format"))
- (cons (const tags) (string :tag "Format"))))
- :group 'org-agenda-prefix)
+ (cons (const tags) (string :tag "Format"))
+ (cons (const search) (string :tag "Format"))))
+ :group 'org-agenda-line-format)
(defvar org-prefix-format-compiled nil
"The compiled version of the most recently used prefix format.
See the variable `org-agenda-prefix-format'.")
+(defcustom org-agenda-todo-keyword-format "%-1s"
+ "Format for the TODO keyword in agenda lines.
+Set this to something like \"%-12s\" if you want all TODO keywords
+to occupy a fixed space in the agenda display."
+ :group 'org-agenda-line-format
+ :type 'string)
+
+(defcustom org-agenda-scheduled-leaders '("Scheduled: " "Sched.%2dx: ")
+ "Text preceeding scheduled items in the agenda view.
+This is a list with two strings. The first applies when the item is
+scheduled on the current day. The second applies when it has been scheduled
+previously, it may contain a %d to capture how many days ago the item was
+scheduled."
+ :group 'org-agenda-line-format
+ :type '(list
+ (string :tag "Scheduled today ")
+ (string :tag "Scheduled previously")))
+
+(defcustom org-agenda-deadline-leaders '("Deadline: " "In %3d d.: ")
+ "Text preceeding deadline items in the agenda view.
+This is a list with two strings. The first applies when the item has its
+deadline on the current day. The second applies when it is in the past or
+in the future, it may contain %d to capture how many days away the deadline
+is (was)."
+ :group 'org-agenda-line-format
+ :type '(list
+ (string :tag "Deadline today ")
+ (string :tag "Deadline relative")))
+
(defcustom org-agenda-remove-times-when-in-prefix t
"Non-nil means, remove duplicate time specifications in agenda items.
When the format `org-agenda-prefix-format' contains a `%t' specifier, a
The option can be t or nil. It may also be the symbol `beg', indicating
that the time should only be removed what it is located at the beginning of
the headline/diary entry."
- :group 'org-agenda-prefix
+ :group 'org-agenda-line-format
:type '(choice
(const :tag "Always" t)
(const :tag "Never" nil)
(const :tag "When at beginning of entry" beg)))
-(defcustom org-agenda-remove-tags-when-in-prefix nil
+
+(defcustom org-agenda-default-appointment-duration nil
+ "Default duration for appointments that only have a starting time.
+When nil, no duration is specified in such cases.
+When non-nil, this must be the number of minutes, e.g. 60 for one hour."
+ :group 'org-agenda-line-format
+ :type '(choice
+ (integer :tag "Minutes")
+ (const :tag "No default duration")))
+
+
+(defcustom org-agenda-remove-tags nil
"Non-nil means, remove the tags from the headline copy in the agenda.
When this is the symbol `prefix', only remove tags when
`org-agenda-prefix-format' contains a `%T' specifier."
- :group 'org-agenda-prefix
+ :group 'org-agenda-line-format
:type '(choice
(const :tag "Always" t)
(const :tag "Never" nil)
(const :tag "When prefix format contains %T" prefix)))
-(defcustom org-agenda-align-tags-to-column 65
- "Shift tags in agenda items to this column."
- :group 'org-agenda-prefix
+(if (fboundp 'defvaralias)
+ (defvaralias 'org-agenda-remove-tags-when-in-prefix
+ 'org-agenda-remove-tags))
+
+(defcustom org-agenda-tags-column -80
+ "Shift tags in agenda items to this column.
+If this number is positive, it specifies the column. If it is negative,
+it means that the tags should be flushright to that column. For example,
+-80 works well for a normal 80 character screen."
+ :group 'org-agenda-line-format
:type 'integer)
+(if (fboundp 'defvaralias)
+ (defvaralias 'org-agenda-align-tags-to-column 'org-agenda-tags-column))
+
+(defcustom org-agenda-fontify-priorities t
+ "Non-nil means, highlight low and high priorities in agenda.
+When t, the highest priority entries are bold, lowest priority italic.
+This may also be an association list of priority faces. The face may be
+a names face, or a list like `(:background \"Red\")'."
+ :group 'org-agenda-line-format
+ :type '(choice
+ (const :tag "Never" nil)
+ (const :tag "Defaults" t)
+ (repeat :tag "Specify"
+ (list (character :tag "Priority" :value ?A)
+ (sexp :tag "face")))))
+
(defgroup org-latex nil
- "Options for embedding LaTeX code into Org-mode"
+ "Options for embedding LaTeX code into Org-mode."
:tag "Org LaTeX"
:group 'org)
(defcustom org-format-latex-options
- '(:foreground "Black" :background "Transparent" :scale 1.0
- :matchers ("begin" "$" "$$" "\\(" "\\["))
+ '(:foreground default :background default :scale 1.0
+ :html-foreground "Black" :html-background "Transparent" :html-scale 1.0
+ :matchers ("begin" "$" "$$" "\\(" "\\["))
"Options for creating images from LaTeX fragments.
This is a property list with the following properties:
-:foreground the foreground color, for example \"Black\".
+:foreground the foreground color for images embedded in emacs, e.g. \"Black\".
+ `default' means use the forground of the default face.
:background the background color, or \"Transparent\".
+ `default' means use the background of the default face.
:scale a scaling factor for the size of the images
+:html-foreground, :html-background, :html-scale
+ The same numbers for HTML export.
:matchers a list indicating which matchers should be used to
find LaTeX fragments. Valid members of this list are:
\"begin\" find environments
:group 'org-latex
:type 'plist)
+(defcustom org-format-latex-header "\\documentclass{article}
+\\usepackage{fullpage} % do not remove
+\\usepackage{amssymb}
+\\usepackage[usenames]{color}
+\\usepackage{amsmath}
+\\usepackage{latexsym}
+\\usepackage[mathscr]{eucal}
+\\pagestyle{empty} % do not remove"
+ "The document header used for processing LaTeX fragments."
+ :group 'org-latex
+ :type 'string)
+
(defgroup org-export nil
"Options for exporting org-listings."
:tag "Org Export"
:tag "Org Export General"
:group 'org-export)
-(defcustom org-export-publishing-directory "."
- "Path to the location where exported files should be located.
-This path may be relative to the directory where the Org-mode file lives.
-The default is to put them into the same directory as the Org-mode file.
-The variable may also be an alist with export types `:html', `:ascii',
-`:ical', or `:xoxo' and the corresponding directories. If a direcoty path
-is relative, it is interpreted relative to the directory where the exported
-Org-mode files lives."
- :group 'org-export-general
- :type '(choice
- (directory)
- (repeat
- (cons
- (choice :tag "Type"
- (const :html) (const :ascii) (const :ical) (const :xoxo))
- (directory)))))
+;; FIXME
+(defvar org-export-publishing-directory nil)
+
+(defcustom org-export-with-special-strings t
+ "Non-nil means, interpret \"\-\", \"--\" and \"---\" for export.
+When this option is turned on, these strings will be exported as:
+
+ Org HTML LaTeX
+ -----+----------+--------
+ \\- ­ \\-
+ -- – --
+ --- — ---
+ ... … \ldots
+
+This option can also be set with the +OPTIONS line, e.g. \"-:nil\"."
+ :group 'org-export-translation
+ :type 'boolean)
(defcustom org-export-language-setup
'(("en" "Author" "Date" "Table of Contents")
("cs" "Autor" "Datum" "Obsah")
("da" "Ophavsmand" "Dato" "Indhold")
("de" "Autor" "Datum" "Inhaltsverzeichnis")
- ("es" "Autor" "Fecha" "\xccndice")
- ("fr" "Auteur" "Date" "Table des Mati\xe8res")
+ ("es" "Autor" "Fecha" "\xcdndice")
+ ("fr" "Auteur" "Date" "Table des mati\xe8res")
("it" "Autore" "Data" "Indice")
("nl" "Auteur" "Datum" "Inhoudsopgave")
("nn" "Forfattar" "Dato" "Innhold") ;; nn = Norsk (nynorsk)
:group 'org-export-general
:type 'string)
+(defcustom org-export-skip-text-before-1st-heading t
+ "Non-nil means, skip all text before the first headline when exporting.
+When nil, that text is exported as well."
+ :group 'org-export-general
+ :type 'boolean)
+
(defcustom org-export-headline-levels 3
"The last level which is still exported as a headline.
Inferior levels will produce itemize lists when exported.
(const :tag "headline only" 'headline)
(const :tag "entirely" t)))
+(defcustom org-export-author-info t
+ "Non-nil means, insert author name and email into the exported file.
+
+This option can also be set with the +OPTIONS line,
+e.g. \"author-info:nil\"."
+ :group 'org-export-general
+ :type 'boolean)
+
+(defcustom org-export-time-stamp-file t
+ "Non-nil means, insert a time stamp into the exported file.
+The time stamp shows when the file was created.
+
+This option can also be set with the +OPTIONS line,
+e.g. \"timestamp:nil\"."
+ :group 'org-export-general
+ :type 'boolean)
+
(defcustom org-export-with-timestamps t
"If nil, do not export time stamps and associated keywords."
:group 'org-export-general
(defcustom org-export-with-tags 'not-in-toc
"If nil, do not export tags, just remove them from headlines.
If this is the symbol `not-in-toc', tags will be removed from table of
-contents entries, but still be shown in the headlines of the document."
+contents entries, but still be shown in the headlines of the document.
+
+This option can also be set with the +OPTIONS line, e.g. \"tags:nil\"."
:group 'org-export-general
:type '(choice
(const :tag "Off" nil)
(const :tag "Not in TOC" not-in-toc)
(const :tag "On" t)))
+(defcustom org-export-with-drawers nil
+ "Non-nil means, export with drawers like the property drawer.
+When t, all drawers are exported. This may also be a list of
+drawer names to export."
+ :group 'org-export-general
+ :type '(choice
+ (const :tag "All drawers" t)
+ (const :tag "None" nil)
+ (repeat :tag "Selected drawers"
+ (string :tag "Drawer name"))))
+
(defgroup org-export-translation nil
"Options for translating special ascii sequences for the export backends."
:tag "Org Export Translation"
:group 'org-export-translation
:type 'boolean)
+(defcustom org-export-with-footnotes t
+ "If nil, export [1] as a footnote marker.
+Lines starting with [1] will be formatted as footnotes.
+
+This option can also be set with the +OPTIONS line, e.g. \"f:nil\"."
+ :group 'org-export-translation
+ :type 'boolean)
+
(defcustom org-export-with-sub-superscripts t
"Non-nil means, interpret \"_\" and \"^\" for export.
When this option is turned on, you can use TeX-like syntax for sub- and
x_{i^2} or x^(2-i) braces or parenthesis do grouping.
Still, ambiguity is possible - so when in doubt use {} to enclose the
-sub/superscript.
+sub/superscript. If you set this variable to the symbol `{}',
+the braces are *required* in order to trigger interpretations as
+sub/superscript. This can be helpful in documents that need \"_\"
+frequently in plain text.
+
Not all export backends support this, but HTML does.
This option can also be set with the +OPTIONS line, e.g. \"^:nil\"."
+ :group 'org-export-translation
+ :type '(choice
+ (const :tag "Always interpret" t)
+ (const :tag "Only with braces" {})
+ (const :tag "Never interpret" nil)))
+
+(defcustom org-export-with-special-strings t
+ "Non-nil means, interpret \"\-\", \"--\" and \"---\" for export.
+When this option is turned on, these strings will be exported as:
+
+\\- : ­
+-- : –
+--- : —
+
+Not all export backends support this, but HTML does.
+
+This option can also be set with the +OPTIONS line, e.g. \"-:nil\"."
:group 'org-export-translation
:type 'boolean)
This option can also be set with the +OPTIONS line, e.g. \"TeX:nil\"."
:group 'org-export-translation
- :group 'org-latex
+ :group 'org-export-latex
:type 'boolean)
(defcustom org-export-with-LaTeX-fragments nil
This option can also be set with the +OPTIONS line, e.g. \"LaTeX:t\"."
:group 'org-export-translation
- :group 'org-latex
+ :group 'org-export-latex
:type 'boolean)
(defcustom org-export-with-fixed-width t
:tag "Org Export HTML"
:group 'org-export)
+(defcustom org-export-html-coding-system nil
+ ""
+ :group 'org-export-html
+ :type 'coding-system)
+
+(defcustom org-export-html-extension "html"
+ "The extension for exported HTML files."
+ :group 'org-export-html
+ :type 'string)
+
(defcustom org-export-html-style
"<style type=\"text/css\">
html {
Since there are different ways of setting style information, this variable
needs to contain the full HTML structure to provide a style, including the
surrounding HTML tags. The style specifications should include definitions
-for new classes todo, done, title, and deadline. For example, legal values
+for new classes todo, done, title, and deadline. For example, valid values
would be:
<style type=\"text/css\">
:group 'org-export-html
:type 'string)
+
(defcustom org-export-html-title-format "<h1 class=\"title\">%s</h1>\n"
"Format for typesetting the document title in HTML export."
:group 'org-export-html
(defcustom org-export-html-table-tag
"<table border=\"2\" cellspacing=\"0\" cellpadding=\"6\" rules=\"groups\" frame=\"hsides\">"
- "The HTML tag used to start a table.
+ "The HTML tag that is used to start a table.
This must be a <table> tag, but you may change the options like
borders and spacing."
:group 'org-export-html
:type 'string)
+(defcustom org-export-table-header-tags '("<th>" . "</th>")
+ "The opening tag for table header fields.
+This is customizable so that alignment options can be specified."
+ :group 'org-export-tables
+ :type '(cons (string :tag "Opening tag") (string :tag "Closing tag")))
+
+(defcustom org-export-table-data-tags '("<td>" . "</td>")
+ "The opening tag for table data fields.
+This is customizable so that alignment options can be specified."
+ :group 'org-export-tables
+ :type '(cons (string :tag "Opening tag") (string :tag "Closing tag")))
+
(defcustom org-export-html-with-timestamp nil
"If non-nil, write `org-export-html-html-helper-timestamp'
into the exported HTML text. Otherwise, the buffer will just be saved
(defcustom org-combined-agenda-icalendar-file "~/org.ics"
"The file name for the iCalendar file covering all agenda files.
This file is created with the command \\[org-export-icalendar-all-agenda-files].
-The file name should be absolute."
+The file name should be absolute, the file will be overwritten without warning."
:group 'org-export-icalendar
:type 'file)
(const :tag "Unfinished" t)
(const :tag "All" all)))
+(defcustom org-icalendar-include-sexps t
+ "Non-nil means, export to iCalendar files should also cover sexp entries.
+These are entries like in the diary, but directly in an Org-mode file."
+ :group 'org-export-icalendar
+ :type 'boolean)
+
+(defcustom org-icalendar-include-body 100
+ "Amount of text below headline to be included in iCalendar export.
+This is a number of characters that should maximally be included.
+Properties, scheduling and clocking lines will always be removed.
+The text will be inserted into the DESCRIPTION field."
+ :group 'org-export-icalendar
+ :type '(choice
+ (const :tag "Nothing" nil)
+ (const :tag "Everything" t)
+ (integer :tag "Max characters")))
+
(defcustom org-icalendar-combined-name "OrgMode"
"Calendar name for the combined iCalendar representing all agenda files."
:group 'org-export-icalendar
:group 'org-font-lock
:type 'boolean)
+(defcustom org-highlight-latex-fragments-and-specials nil
+ "Non-nil means, fontify what is treated specially by the exporters."
+ :group 'org-font-lock
+ :type 'boolean)
+
+(defcustom org-hide-emphasis-markers nil
+ "Non-nil mean font-lock should hide the emphasis marker characters."
+ :group 'org-font-lock
+ :type 'boolean)
+
(defvar org-emph-re nil
"Regular expression for matching emphasis.")
+(defvar org-verbatim-re nil
+ "Regular expression for matching verbatim text.")
(defvar org-emphasis-regexp-components) ; defined just below
(defvar org-emphasis-alist) ; defined just below
(defun org-set-emph-re (var val)
(border (nth 2 e))
(body (nth 3 e))
(nl (nth 4 e))
- (stacked (nth 5 e))
+ (stacked (and nil (nth 5 e))) ; stacked is no longer allowed, forced to nil
(body1 (concat body "*?"))
- (markers (mapconcat 'car org-emphasis-alist "")))
+ (markers (mapconcat 'car org-emphasis-alist ""))
+ (vmarkers (mapconcat
+ (lambda (x) (if (eq (nth 4 x) 'verbatim) (car x) ""))
+ org-emphasis-alist "")))
;; make sure special characters appear at the right position in the class
(if (string-match "\\^" markers)
(setq markers (concat (replace-match "" t t markers) "^")))
(if (string-match "-" markers)
(setq markers (concat (replace-match "" t t markers) "-")))
-; (while (>= (setq nl (1- nl)) 0) (setq body1 (concat body1 "\n?" body "*?")))
-; (while (>= (setq nl (1- nl)) 0) (setq body1 (concat body1 "\\(?:\n?" body "*?\\)?")))
+ (if (string-match "\\^" vmarkers)
+ (setq vmarkers (concat (replace-match "" t t vmarkers) "^")))
+ (if (string-match "-" vmarkers)
+ (setq vmarkers (concat (replace-match "" t t vmarkers) "-")))
(if (> nl 0)
(setq body1 (concat body1 "\\(?:\n" body "*?\\)\\{0,"
(int-to-string nl) "\\}")))
;; Make the regexp
(setq org-emph-re
- (concat "\\([" pre (if stacked markers) "]\\|^\\)"
+ (concat "\\([" pre (if (and nil stacked) markers) "]\\|^\\)"
"\\("
"\\([" markers "]\\)"
"\\("
- "[^" border markers "]"
+ "[^" border "]\\|"
+ "[^" border (if (and nil stacked) markers) "]"
+ body1
+ "[^" border (if (and nil stacked) markers) "]"
+ "\\)"
+ "\\3\\)"
+ "\\([" post (if (and nil stacked) markers) "]\\|$\\)"))
+ (setq org-verbatim-re
+ (concat "\\([" pre "]\\|^\\)"
+ "\\("
+ "\\([" vmarkers "]\\)"
+ "\\("
+ "[^" border "]\\|"
+ "[^" border "]"
body1
- "[^" border markers "]"
+ "[^" border "]"
"\\)"
"\\3\\)"
- "\\([" post (if stacked markers) "]\\|$\\)")))))
+ "\\([" post "]\\|$\\)")))))
(defcustom org-emphasis-regexp-components
- '(" \t('\"" " \t.,?;'\")" " \t\r\n," "." 1 nil)
- "Components used to build the reqular expression for emphasis.
+ '(" \t('\"" "- \t.,:?;'\")" " \t\r\n,\"'" "." 1)
+ "Components used to build the regular expression for emphasis.
This is a list with 6 entries. Terminology: In an emphasis string
like \" *strong word* \", we call the initial space PREMATCH, the final
space POSTMATCH, the stars MARKERS, \"s\" and \"d\" are BORDER characters
pre Chars allowed as prematch. Beginning of line will be allowed too.
post Chars allowed as postmatch. End of line will be allowed too.
-border The chars *forbidden* as border characters. In addition to the
- characters given here, all marker characters are forbidden too.
+border The chars *forbidden* as border characters.
body-regexp A regexp like \".\" to match a body character. Don't use
non-shy groups here, and don't allow newline here.
newline The maximum number of newlines allowed in an emphasis exp.
-stacked Non-nil means, allow stacked styles. This works only in HTML
- export. When this is set, all marker characters (as given in
- `org-emphasis-alist') will be allowed as pre/post, aiding
- inside-out matching.
+
Use customize to modify this, or restart Emacs after changing it."
:group 'org-font-lock
:set 'org-set-emph-re
(sexp :tag "Forbidden chars in border ")
(sexp :tag "Regexp for body ")
(integer :tag "number of newlines allowed")
- (boolean :tag "Stacking allowed ")))
+ (option (boolean :tag "Stacking (DISABLED) "))))
(defcustom org-emphasis-alist
'(("*" bold "<b>" "</b>")
("/" italic "<i>" "</i>")
("_" underline "<u>" "</u>")
- ("=" shadow "<code>" "</code>")
+ ("=" org-code "<code>" "</code>" verbatim)
+ ("~" org-verbatim "" "" verbatim)
("+" (:strike-through t) "<del>" "</del>")
-)
-"Special syntax for emphasized text.
+ )
+ "Special syntax for emphasized text.
Text starting and ending with a special character will be emphasized, for
example *bold*, _underlined_ and /italic/. This variable sets the marker
-characters, the face to bbe used by font-lock for highlighting in Org-mode
+characters, the face to be used by font-lock for highlighting in Org-mode
Emacs buffers, and the HTML tags to be used for this.
Use customize to modify this, or restart Emacs after changing it."
:group 'org-font-lock
(face :tag "Font-lock-face")
(plist :tag "Face property list"))
(string :tag "HTML start tag")
- (string :tag "HTML end tag"))))
+ (string :tag "HTML end tag")
+ (option (const verbatim)))))
;;; The faces
:tag "Org Faces"
:group 'org-font-lock)
-(defun org-compatible-face (specs)
+(defun org-compatible-face (inherits specs)
"Make a compatible face specification.
+If INHERITS is an existing face and if the Emacs version supports it,
+just inherit the face. If not, use SPECS to define the face.
XEmacs and Emacs 21 do not know about the `min-colors' attribute.
For them we convert a (min-colors 8) entry to a `tty' entry and move it
to the top of the list. The `min-colors' attribute will be removed from
any other entries, and any resulting duplicates will be removed entirely."
- (if (or (featurep 'xemacs) (< emacs-major-version 22))
- (let (r e a)
- (while (setq e (pop specs))
- (cond
- ((memq (car e) '(t default)) (push e r))
- ((setq a (member '(min-colors 8) (car e)))
- (nconc r (list (cons (cons '(type tty) (delq (car a) (car e)))
- (cdr e)))))
- ((setq a (assq 'min-colors (car e)))
- (setq e (cons (delq a (car e)) (cdr e)))
- (or (assoc (car e) r) (push e r)))
- (t (or (assoc (car e) r) (push e r)))))
- (nreverse r))
- specs))
+ (cond
+ ((and inherits (facep inherits)
+ (not (featurep 'xemacs)) (> emacs-major-version 22))
+ ;; In Emacs 23, we use inheritance where possible.
+ ;; We only do this in Emacs 23, because only there the outline
+ ;; faces have been changed to the original org-mode-level-faces.
+ (list (list t :inherit inherits)))
+ ((or (featurep 'xemacs) (< emacs-major-version 22))
+ ;; These do not understand the `min-colors' attribute.
+ (let (r e a)
+ (while (setq e (pop specs))
+ (cond
+ ((memq (car e) '(t default)) (push e r))
+ ((setq a (member '(min-colors 8) (car e)))
+ (nconc r (list (cons (cons '(type tty) (delq (car a) (car e)))
+ (cdr e)))))
+ ((setq a (assq 'min-colors (car e)))
+ (setq e (cons (delq a (car e)) (cdr e)))
+ (or (assoc (car e) r) (push e r)))
+ (t (or (assoc (car e) r) (push e r)))))
+ (nreverse r)))
+ (t specs)))
+(put 'org-compatible-face 'lisp-indent-function 1)
(defface org-hide
'((((background light)) (:foreground "white"))
:group 'org-faces)
(defface org-level-1 ;; font-lock-function-name-face
- (org-compatible-face
- '((((class color) (min-colors 88) (background light)) (:foreground "Blue1"))
- (((class color) (min-colors 88) (background dark)) (:foreground "LightSkyBlue"))
- (((class color) (min-colors 16) (background light)) (:foreground "Blue"))
- (((class color) (min-colors 16) (background dark)) (:foreground "LightSkyBlue"))
- (((class color) (min-colors 8)) (:foreground "blue" :bold t))
- (t (:bold t))))
+ (org-compatible-face 'outline-1
+ '((((class color) (min-colors 88) (background light)) (:foreground "Blue1"))
+ (((class color) (min-colors 88) (background dark)) (:foreground "LightSkyBlue"))
+ (((class color) (min-colors 16) (background light)) (:foreground "Blue"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "LightSkyBlue"))
+ (((class color) (min-colors 8)) (:foreground "blue" :bold t))
+ (t (:bold t))))
"Face used for level 1 headlines."
:group 'org-faces)
(defface org-level-2 ;; font-lock-variable-name-face
- (org-compatible-face
- '((((class color) (min-colors 16) (background light)) (:foreground "DarkGoldenrod"))
- (((class color) (min-colors 16) (background dark)) (:foreground "LightGoldenrod"))
- (((class color) (min-colors 8) (background light)) (:foreground "yellow"))
- (((class color) (min-colors 8) (background dark)) (:foreground "yellow" :bold t))
- (t (:bold t))))
+ (org-compatible-face 'outline-2
+ '((((class color) (min-colors 16) (background light)) (:foreground "DarkGoldenrod"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "LightGoldenrod"))
+ (((class color) (min-colors 8) (background light)) (:foreground "yellow"))
+ (((class color) (min-colors 8) (background dark)) (:foreground "yellow" :bold t))
+ (t (:bold t))))
"Face used for level 2 headlines."
:group 'org-faces)
(defface org-level-3 ;; font-lock-keyword-face
- (org-compatible-face
- '((((class color) (min-colors 88) (background light)) (:foreground "Purple"))
- (((class color) (min-colors 88) (background dark)) (:foreground "Cyan1"))
- (((class color) (min-colors 16) (background light)) (:foreground "Purple"))
- (((class color) (min-colors 16) (background dark)) (:foreground "Cyan"))
- (((class color) (min-colors 8) (background light)) (:foreground "purple" :bold t))
- (((class color) (min-colors 8) (background dark)) (:foreground "cyan" :bold t))
- (t (:bold t))))
+ (org-compatible-face 'outline-3
+ '((((class color) (min-colors 88) (background light)) (:foreground "Purple"))
+ (((class color) (min-colors 88) (background dark)) (:foreground "Cyan1"))
+ (((class color) (min-colors 16) (background light)) (:foreground "Purple"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "Cyan"))
+ (((class color) (min-colors 8) (background light)) (:foreground "purple" :bold t))
+ (((class color) (min-colors 8) (background dark)) (:foreground "cyan" :bold t))
+ (t (:bold t))))
"Face used for level 3 headlines."
:group 'org-faces)
(defface org-level-4 ;; font-lock-comment-face
- (org-compatible-face
- '((((class color) (min-colors 88) (background light)) (:foreground "Firebrick"))
- (((class color) (min-colors 88) (background dark)) (:foreground "chocolate1"))
- (((class color) (min-colors 16) (background light)) (:foreground "red"))
- (((class color) (min-colors 16) (background dark)) (:foreground "red1"))
- (((class color) (min-colors 8) (background light)) (:foreground "red" :bold t))
- (((class color) (min-colors 8) (background dark)) (:foreground "red" :bold t))
- (t (:bold t))))
+ (org-compatible-face 'outline-4
+ '((((class color) (min-colors 88) (background light)) (:foreground "Firebrick"))
+ (((class color) (min-colors 88) (background dark)) (:foreground "chocolate1"))
+ (((class color) (min-colors 16) (background light)) (:foreground "red"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "red1"))
+ (((class color) (min-colors 8) (background light)) (:foreground "red" :bold t))
+ (((class color) (min-colors 8) (background dark)) (:foreground "red" :bold t))
+ (t (:bold t))))
"Face used for level 4 headlines."
:group 'org-faces)
(defface org-level-5 ;; font-lock-type-face
- (org-compatible-face
- '((((class color) (min-colors 16) (background light)) (:foreground "ForestGreen"))
- (((class color) (min-colors 16) (background dark)) (:foreground "PaleGreen"))
- (((class color) (min-colors 8)) (:foreground "green"))))
+ (org-compatible-face 'outline-5
+ '((((class color) (min-colors 16) (background light)) (:foreground "ForestGreen"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "PaleGreen"))
+ (((class color) (min-colors 8)) (:foreground "green"))))
"Face used for level 5 headlines."
:group 'org-faces)
(defface org-level-6 ;; font-lock-constant-face
- (org-compatible-face
- '((((class color) (min-colors 16) (background light)) (:foreground "CadetBlue"))
- (((class color) (min-colors 16) (background dark)) (:foreground "Aquamarine"))
- (((class color) (min-colors 8)) (:foreground "magenta"))))
+ (org-compatible-face 'outline-6
+ '((((class color) (min-colors 16) (background light)) (:foreground "CadetBlue"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "Aquamarine"))
+ (((class color) (min-colors 8)) (:foreground "magenta"))))
"Face used for level 6 headlines."
:group 'org-faces)
(defface org-level-7 ;; font-lock-builtin-face
- (org-compatible-face
- '((((class color) (min-colors 16) (background light)) (:foreground "Orchid"))
- (((class color) (min-colors 16) (background dark)) (:foreground "LightSteelBlue"))
- (((class color) (min-colors 8)) (:foreground "blue"))))
+ (org-compatible-face 'outline-7
+ '((((class color) (min-colors 16) (background light)) (:foreground "Orchid"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "LightSteelBlue"))
+ (((class color) (min-colors 8)) (:foreground "blue"))))
"Face used for level 7 headlines."
:group 'org-faces)
(defface org-level-8 ;; font-lock-string-face
- (org-compatible-face
- '((((class color) (min-colors 16) (background light)) (:foreground "RosyBrown"))
- (((class color) (min-colors 16) (background dark)) (:foreground "LightSalmon"))
- (((class color) (min-colors 8)) (:foreground "green"))))
+ (org-compatible-face 'outline-8
+ '((((class color) (min-colors 16) (background light)) (:foreground "RosyBrown"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "LightSalmon"))
+ (((class color) (min-colors 8)) (:foreground "green"))))
"Face used for level 8 headlines."
:group 'org-faces)
(defface org-special-keyword ;; font-lock-string-face
- (org-compatible-face
- '((((class color) (min-colors 16) (background light)) (:foreground "RosyBrown"))
- (((class color) (min-colors 16) (background dark)) (:foreground "LightSalmon"))
- (t (:italic t))))
+ (org-compatible-face nil
+ '((((class color) (min-colors 16) (background light)) (:foreground "RosyBrown"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "LightSalmon"))
+ (t (:italic t))))
"Face used for special keywords."
:group 'org-faces)
-(defface org-warning ;; font-lock-warning-face
- (org-compatible-face
- '((((class color) (min-colors 16) (background light)) (:foreground "Red1" :bold t))
- (((class color) (min-colors 16) (background dark)) (:foreground "Pink" :bold t))
- (((class color) (min-colors 8) (background light)) (:foreground "red" :bold t))
- (((class color) (min-colors 8) (background dark)) (:foreground "red" :bold t))
- (t (:bold t))))
- "Face for deadlines and TODO keywords."
+(defface org-drawer ;; font-lock-function-name-face
+ (org-compatible-face nil
+ '((((class color) (min-colors 88) (background light)) (:foreground "Blue1"))
+ (((class color) (min-colors 88) (background dark)) (:foreground "LightSkyBlue"))
+ (((class color) (min-colors 16) (background light)) (:foreground "Blue"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "LightSkyBlue"))
+ (((class color) (min-colors 8)) (:foreground "blue" :bold t))
+ (t (:bold t))))
+ "Face used for drawers."
:group 'org-faces)
-(defface org-headline-done ;; font-lock-string-face
- (org-compatible-face
- '((((class color) (min-colors 16) (background light)) (:foreground "RosyBrown"))
- (((class color) (min-colors 16) (background dark)) (:foreground "LightSalmon"))
- (((class color) (min-colors 8) (background light)) (:bold nil))))
- "Face used to indicate that a headline is DONE.
-This face is only used if `org-fontify-done-headline' is set."
+(defface org-property-value nil
+ "Face used for the value of a property."
+ :group 'org-faces)
+
+(defface org-column
+ (org-compatible-face nil
+ '((((class color) (min-colors 16) (background light))
+ (:background "grey90"))
+ (((class color) (min-colors 16) (background dark))
+ (:background "grey30"))
+ (((class color) (min-colors 8))
+ (:background "cyan" :foreground "black"))
+ (t (:inverse-video t))))
+ "Face for column display of entry properties."
+ :group 'org-faces)
+
+(when (fboundp 'set-face-attribute)
+ ;; Make sure that a fixed-width face is used when we have a column table.
+ (set-face-attribute 'org-column nil
+ :height (face-attribute 'default :height)
+ :family (face-attribute 'default :family)))
+
+(defface org-warning
+ (org-compatible-face 'font-lock-warning-face
+ '((((class color) (min-colors 16) (background light)) (:foreground "Red1" :bold t))
+ (((class color) (min-colors 16) (background dark)) (:foreground "Pink" :bold t))
+ (((class color) (min-colors 8) (background light)) (:foreground "red" :bold t))
+ (((class color) (min-colors 8) (background dark)) (:foreground "red" :bold t))
+ (t (:bold t))))
+ "Face for deadlines and TODO keywords."
:group 'org-faces)
(defface org-archived ; similar to shadow
- (org-compatible-face
- '((((class color grayscale) (min-colors 88) (background light))
- (:foreground "grey50"))
- (((class color grayscale) (min-colors 88) (background dark))
- (:foreground "grey70"))
- (((class color) (min-colors 8) (background light))
- (:foreground "green"))
- (((class color) (min-colors 8) (background dark))
- (:foreground "yellow"))))
- "Face for headline with the ARCHIVE tag."
- :group 'org-faces)
+ (org-compatible-face 'shadow
+ '((((class color grayscale) (min-colors 88) (background light))
+ (:foreground "grey50"))
+ (((class color grayscale) (min-colors 88) (background dark))
+ (:foreground "grey70"))
+ (((class color) (min-colors 8) (background light))
+ (:foreground "green"))
+ (((class color) (min-colors 8) (background dark))
+ (:foreground "yellow"))))
+ "Face for headline with the ARCHIVE tag."
+ :group 'org-faces)
(defface org-link
'((((class color) (background light)) (:foreground "Purple" :underline t))
"Face for links."
:group 'org-faces)
+(defface org-ellipsis
+ '((((class color) (background light)) (:foreground "DarkGoldenrod" :underline t))
+ (((class color) (background dark)) (:foreground "LightGoldenrod" :underline t))
+ (t (:strike-through t)))
+ "Face for the ellipsis in folded text."
+ :group 'org-faces)
+
+(defface org-target
+ '((((class color) (background light)) (:underline t))
+ (((class color) (background dark)) (:underline t))
+ (t (:underline t)))
+ "Face for links."
+ :group 'org-faces)
+
(defface org-date
'((((class color) (background light)) (:foreground "Purple" :underline t))
(((class color) (background dark)) (:foreground "Cyan" :underline t))
"Face for links."
:group 'org-faces)
+(defface org-sexp-date
+ '((((class color) (background light)) (:foreground "Purple"))
+ (((class color) (background dark)) (:foreground "Cyan"))
+ (t (:underline t)))
+ "Face for links."
+ :group 'org-faces)
+
(defface org-tag
'((t (:bold t)))
"Face for tags."
:group 'org-faces)
-(defface org-todo ;; font-lock-warning-face
- (org-compatible-face
- '((((class color) (min-colors 16) (background light)) (:foreground "Red1" :bold t))
- (((class color) (min-colors 16) (background dark)) (:foreground "Pink" :bold t))
- (((class color) (min-colors 8) (background light)) (:foreground "red" :bold t))
- (((class color) (min-colors 8) (background dark)) (:foreground "red" :bold t))
- (t (:inverse-video t :bold t))))
+(defface org-todo ; font-lock-warning-face
+ (org-compatible-face nil
+ '((((class color) (min-colors 16) (background light)) (:foreground "Red1" :bold t))
+ (((class color) (min-colors 16) (background dark)) (:foreground "Pink" :bold t))
+ (((class color) (min-colors 8) (background light)) (:foreground "red" :bold t))
+ (((class color) (min-colors 8) (background dark)) (:foreground "red" :bold t))
+ (t (:inverse-video t :bold t))))
"Face for TODO keywords."
:group 'org-faces)
(defface org-done ;; font-lock-type-face
- (org-compatible-face
- '((((class color) (min-colors 16) (background light)) (:foreground "ForestGreen" :bold t))
- (((class color) (min-colors 16) (background dark)) (:foreground "PaleGreen" :bold t))
- (((class color) (min-colors 8)) (:foreground "green"))
- (t (:bold t))))
- "Face used for DONE."
+ (org-compatible-face nil
+ '((((class color) (min-colors 16) (background light)) (:foreground "ForestGreen" :bold t))
+ (((class color) (min-colors 16) (background dark)) (:foreground "PaleGreen" :bold t))
+ (((class color) (min-colors 8)) (:foreground "green"))
+ (t (:bold t))))
+ "Face used for todo keywords that indicate DONE items."
+ :group 'org-faces)
+
+(defface org-headline-done ;; font-lock-string-face
+ (org-compatible-face nil
+ '((((class color) (min-colors 16) (background light)) (:foreground "RosyBrown"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "LightSalmon"))
+ (((class color) (min-colors 8) (background light)) (:bold nil))))
+ "Face used to indicate that a headline is DONE.
+This face is only used if `org-fontify-done-headline' is set. If applies
+to the part of the headline after the DONE keyword."
:group 'org-faces)
+(defcustom org-todo-keyword-faces nil
+ "Faces for specific TODO keywords.
+This is a list of cons cells, with TODO keywords in the car
+and faces in the cdr. The face can be a symbol, or a property
+list of attributes, like (:foreground \"blue\" :weight bold :underline t)."
+ :group 'org-faces
+ :group 'org-todo
+ :type '(repeat
+ (cons
+ (string :tag "keyword")
+ (sexp :tag "face"))))
+
(defface org-table ;; font-lock-function-name-face
- (org-compatible-face
- '((((class color) (min-colors 88) (background light)) (:foreground "Blue1"))
- (((class color) (min-colors 88) (background dark)) (:foreground "LightSkyBlue"))
- (((class color) (min-colors 16) (background light)) (:foreground "Blue"))
- (((class color) (min-colors 16) (background dark)) (:foreground "LightSkyBlue"))
- (((class color) (min-colors 8) (background light)) (:foreground "blue"))
- (((class color) (min-colors 8) (background dark)))))
+ (org-compatible-face nil
+ '((((class color) (min-colors 88) (background light)) (:foreground "Blue1"))
+ (((class color) (min-colors 88) (background dark)) (:foreground "LightSkyBlue"))
+ (((class color) (min-colors 16) (background light)) (:foreground "Blue"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "LightSkyBlue"))
+ (((class color) (min-colors 8) (background light)) (:foreground "blue"))
+ (((class color) (min-colors 8) (background dark)))))
"Face used for tables."
:group 'org-faces)
(defface org-formula
- (org-compatible-face
- '((((class color) (min-colors 88) (background light)) (:foreground "Firebrick"))
- (((class color) (min-colors 88) (background dark)) (:foreground "chocolate1"))
- (((class color) (min-colors 8) (background light)) (:foreground "red"))
- (((class color) (min-colors 8) (background dark)) (:foreground "red"))
- (t (:bold t :italic t))))
+ (org-compatible-face nil
+ '((((class color) (min-colors 88) (background light)) (:foreground "Firebrick"))
+ (((class color) (min-colors 88) (background dark)) (:foreground "chocolate1"))
+ (((class color) (min-colors 8) (background light)) (:foreground "red"))
+ (((class color) (min-colors 8) (background dark)) (:foreground "red"))
+ (t (:bold t :italic t))))
"Face for formulas."
:group 'org-faces)
+(defface org-code
+ (org-compatible-face nil
+ '((((class color grayscale) (min-colors 88) (background light))
+ (:foreground "grey50"))
+ (((class color grayscale) (min-colors 88) (background dark))
+ (:foreground "grey70"))
+ (((class color) (min-colors 8) (background light))
+ (:foreground "green"))
+ (((class color) (min-colors 8) (background dark))
+ (:foreground "yellow"))))
+ "Face for fixed-with text like code snippets."
+ :group 'org-faces
+ :version "22.1")
+
+(defface org-verbatim
+ (org-compatible-face nil
+ '((((class color grayscale) (min-colors 88) (background light))
+ (:foreground "grey50" :underline t))
+ (((class color grayscale) (min-colors 88) (background dark))
+ (:foreground "grey70" :underline t))
+ (((class color) (min-colors 8) (background light))
+ (:foreground "green" :underline t))
+ (((class color) (min-colors 8) (background dark))
+ (:foreground "yellow" :underline t))))
+ "Face for fixed-with text like code snippets."
+ :group 'org-faces
+ :version "22.1")
+
+(defface org-agenda-structure ;; font-lock-function-name-face
+ (org-compatible-face nil
+ '((((class color) (min-colors 88) (background light)) (:foreground "Blue1"))
+ (((class color) (min-colors 88) (background dark)) (:foreground "LightSkyBlue"))
+ (((class color) (min-colors 16) (background light)) (:foreground "Blue"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "LightSkyBlue"))
+ (((class color) (min-colors 8)) (:foreground "blue" :bold t))
+ (t (:bold t))))
+ "Face used in agenda for captions and dates."
+ :group 'org-faces)
+
(defface org-scheduled-today
- (org-compatible-face
- '((((class color) (min-colors 88) (background light)) (:foreground "DarkGreen"))
- (((class color) (min-colors 88) (background dark)) (:foreground "PaleGreen"))
- (((class color) (min-colors 8)) (:foreground "green"))
- (t (:bold t :italic t))))
+ (org-compatible-face nil
+ '((((class color) (min-colors 88) (background light)) (:foreground "DarkGreen"))
+ (((class color) (min-colors 88) (background dark)) (:foreground "PaleGreen"))
+ (((class color) (min-colors 8)) (:foreground "green"))
+ (t (:bold t :italic t))))
"Face for items scheduled for a certain day."
:group 'org-faces)
(defface org-scheduled-previously
- (org-compatible-face
- '((((class color) (min-colors 88) (background light)) (:foreground "Firebrick"))
- (((class color) (min-colors 88) (background dark)) (:foreground "chocolate1"))
- (((class color) (min-colors 8) (background light)) (:foreground "red"))
- (((class color) (min-colors 8) (background dark)) (:foreground "red" :bold t))
- (t (:bold t))))
+ (org-compatible-face nil
+ '((((class color) (min-colors 88) (background light)) (:foreground "Firebrick"))
+ (((class color) (min-colors 88) (background dark)) (:foreground "chocolate1"))
+ (((class color) (min-colors 8) (background light)) (:foreground "red"))
+ (((class color) (min-colors 8) (background dark)) (:foreground "red" :bold t))
+ (t (:bold t))))
"Face for items scheduled previously, and not yet done."
:group 'org-faces)
(defface org-upcoming-deadline
- (org-compatible-face
- '((((class color) (min-colors 88) (background light)) (:foreground "Firebrick"))
- (((class color) (min-colors 88) (background dark)) (:foreground "chocolate1"))
- (((class color) (min-colors 8) (background light)) (:foreground "red"))
- (((class color) (min-colors 8) (background dark)) (:foreground "red" :bold t))
- (t (:bold t))))
+ (org-compatible-face nil
+ '((((class color) (min-colors 88) (background light)) (:foreground "Firebrick"))
+ (((class color) (min-colors 88) (background dark)) (:foreground "chocolate1"))
+ (((class color) (min-colors 8) (background light)) (:foreground "red"))
+ (((class color) (min-colors 8) (background dark)) (:foreground "red" :bold t))
+ (t (:bold t))))
"Face for items scheduled previously, and not yet done."
:group 'org-faces)
+(defcustom org-agenda-deadline-faces
+ '((1.0 . org-warning)
+ (0.5 . org-upcoming-deadline)
+ (0.0 . default))
+ "Faces for showing deadlines in the agenda.
+This is a list of cons cells. The cdr of each cell is a face to be used,
+and it can also just be like '(:foreground \"yellow\").
+Each car is a fraction of the head-warning time that must have passed for
+this the face in the cdr to be used for display. The numbers must be
+given in descending order. The head-warning time is normally taken
+from `org-deadline-warning-days', but can also be specified in the deadline
+timestamp itself, like this:
+
+ DEADLINE: <2007-08-13 Mon -8d>
+
+You may use d for days, w for weeks, m for months and y for years. Months
+and years will only be treated in an approximate fashion (30.4 days for a
+month and 365.24 days for a year)."
+ :group 'org-faces
+ :group 'org-agenda-daily/weekly
+ :type '(repeat
+ (cons
+ (number :tag "Fraction of head-warning time passed")
+ (sexp :tag "Face"))))
+
+;; FIXME: this is not a good face yet.
+(defface org-agenda-restriction-lock
+ (org-compatible-face nil
+ '((((class color) (min-colors 88) (background light)) (:background "yellow1"))
+ (((class color) (min-colors 88) (background dark)) (:background "skyblue4"))
+ (((class color) (min-colors 16) (background light)) (:background "yellow1"))
+ (((class color) (min-colors 16) (background dark)) (:background "skyblue4"))
+ (((class color) (min-colors 8)) (:background "cyan" :foreground "black"))
+ (t (:inverse-video t))))
+ "Face for showing the agenda restriction lock."
+ :group 'org-faces)
+
(defface org-time-grid ;; font-lock-variable-name-face
- (org-compatible-face
- '((((class color) (min-colors 16) (background light)) (:foreground "DarkGoldenrod"))
- (((class color) (min-colors 16) (background dark)) (:foreground "LightGoldenrod"))
- (((class color) (min-colors 8)) (:foreground "yellow" :weight light))))
+ (org-compatible-face nil
+ '((((class color) (min-colors 16) (background light)) (:foreground "DarkGoldenrod"))
+ (((class color) (min-colors 16) (background dark)) (:foreground "LightGoldenrod"))
+ (((class color) (min-colors 8)) (:foreground "yellow" :weight light))))
"Face used for time grids."
:group 'org-faces)
'(org-level-1 org-level-2 org-level-3 org-level-4
org-level-5 org-level-6 org-level-7 org-level-8
))
-(defconst org-n-levels (length org-level-faces))
+(defcustom org-n-level-faces (length org-level-faces)
+ "The number of different faces to be used for headlines.
+Org-mode defines 8 different headline faces, so this can be at most 8.
+If it is less than 8, the level-1 face gets re-used for level N+1 etc."
+ :type 'number
+ :group 'org-faces)
+
+;;; Variables from ther packages declared here to avoid compiler warnings
+
+;; XEmacs only
+(defvar outline-mode-menu-heading)
+(defvar outline-mode-menu-show)
+(defvar outline-mode-menu-hide)
+(defvar zmacs-regions) ; XEmacs regions
+
+;; Emacs only
+(defvar mark-active)
+
+;; Various packages
+;; FIXME: get the argument lists for the UNKNOWN stuff
+(defvar calc-embedded-close-formula)
+(defvar calc-embedded-open-formula)
+(defvar calendar-mode-map)
+(defvar original-date) ; dynamically scoped in calendar.el does scope this
+(defvar font-lock-unfontify-region-function)
+(defvar gnus-other-frame-object)
+(defvar gnus-group-name)
+(defvar gnus-article-current)
+(defvar Info-current-file)
+(defvar Info-current-node)
+(defvar mh-progs)
+(defvar mh-current-folder)
+(defvar mh-show-folder-buffer)
+(defvar mh-index-folder)
+(defvar mh-searcher)
+
+(defvar remember-save-after-remembering)
+(defvar remember-data-file)
+(defvar remember-register)
+(defvar remember-buffer)
+(defvar remember-handler-functions)
+(defvar remember-annotation-functions)
+(defvar rmail-current-message)
+(defvar texmathp-why)
+(defvar vm-message-pointer)
+(defvar vm-folder-directory)
+(defvar w3m-current-url)
+(defvar w3m-current-title)
+;; backward compatibility to old version of wl
+(defvar wl-summary-buffer-elmo-folder)
+(defvar wl-summary-buffer-folder-name)
+
+(defvar org-latex-regexps)
+(defvar constants-unit-system)
;;; Variables for pre-computed regular expressions, all buffer local
-(defvar org-done-string nil
- "The last string in `org-todo-keywords', indicating an item is DONE.")
-(make-variable-buffer-local 'org-done-string)
+(defvar org-drawer-regexp nil
+ "Matches first line of a hidden block.")
+(make-variable-buffer-local 'org-drawer-regexp)
(defvar org-todo-regexp nil
"Matches any of the TODO state keywords.")
(make-variable-buffer-local 'org-todo-regexp)
(defvar org-todo-line-regexp nil
"Matches a headline and puts TODO state into group 2 if present.")
(make-variable-buffer-local 'org-todo-line-regexp)
+(defvar org-complex-heading-regexp nil
+ "Matches a headline and puts everything into groups:
+group 1: the stars
+group 2: The todo keyword, maybe
+group 3: Priority cookie
+group 4: True headline
+group 5: Tags")
+(make-variable-buffer-local 'org-complex-heading-regexp)
(defvar org-todo-line-tags-regexp nil
"Matches a headline and puts TODO state into group 2 if present.
Also put tags into group 4 if tags are present.")
(defvar org-looking-at-done-regexp nil
"Matches the DONE keyword a point.")
(make-variable-buffer-local 'org-looking-at-done-regexp)
-(defvar org-todo-kwd-priority-p nil
- "Do TODO items have priorities?")
-(make-variable-buffer-local 'org-todo-kwd-priority-p)
-(defvar org-todo-kwd-max-priority nil
- "Maximum priority of TODO items.")
-(make-variable-buffer-local 'org-todo-kwd-max-priority)
(defvar org-ds-keyword-length 12
"Maximum length of the Deadline and SCHEDULED keywords.")
(make-variable-buffer-local 'org-ds-keyword-length)
(defvar org-maybe-keyword-time-regexp nil
"Matches a timestamp, possibly preceeded by a keyword.")
(make-variable-buffer-local 'org-maybe-keyword-time-regexp)
+(defvar org-planning-or-clock-line-re nil
+ "Matches a line with planning or clock info.")
+(make-variable-buffer-local 'org-planning-or-clock-line-re)
(defconst org-rm-props '(invisible t face t keymap t intangible t mouse-face t
rear-nonsticky t mouse-map t fontified t)
(match-string-no-properties num string)))
(defsubst org-no-properties (s)
- (remove-text-properties 0 (length s) org-rm-props s)
+ (if (fboundp 'set-text-properties)
+ (set-text-properties 0 (length s) nil s)
+ (remove-text-properties 0 (length s) org-rm-props s))
s)
(defsubst org-get-alist-option (option key)
((assoc key option) (cdr (assoc key option)))
(t (cdr (assq 'default option)))))
+(defsubst org-inhibit-invisibility ()
+ "Modified `buffer-invisibility-spec' for Emacs 21.
+Some ops with invisible text do not work correctly on Emacs 21. For these
+we turn off invisibility temporarily. Use this in a `let' form."
+ (if (< emacs-major-version 22) nil buffer-invisibility-spec))
+
(defsubst org-set-local (var value)
"Make VAR local in current buffer and set it to VALUE."
(set (make-variable-buffer-local var) value))
("align" org-startup-align-all-tables t)
("noalign" org-startup-align-all-tables nil)
("customtime" org-display-custom-times t)
- ("logging" org-log-done t)
- ("logdone" org-log-done t)
- ("nologging" org-log-done nil)
- ("lognotedone" org-log-done done push)
- ("lognotestate" org-log-done state push)
- ("lognoteclock-out" org-log-done clock-out push))
+ ("logdone" org-log-done time)
+ ("lognotedone" org-log-done note)
+ ("nologdone" org-log-done nil)
+ ("lognoteclock-out" org-log-note-clock-out t)
+ ("nolognoteclock-out" org-log-note-clock-out nil)
+ ("logrepeat" org-log-repeat state)
+ ("lognoterepeat" org-log-repeat note)
+ ("nologrepeat" org-log-repeat nil)
+ ("constcgs" constants-unit-system cgs)
+ ("constSI" constants-unit-system SI))
"Variable associated with STARTUP options for org-mode.
Each element is a list of three items: The startup options as written
in the #+STARTUP line, the corresponding variable, and the value to
(defun org-set-regexps-and-options ()
"Precompute regular expressions for current buffer."
(when (org-mode-p)
+ (org-set-local 'org-todo-kwd-alist nil)
+ (org-set-local 'org-todo-key-alist nil)
+ (org-set-local 'org-todo-key-trigger nil)
+ (org-set-local 'org-todo-keywords-1 nil)
+ (org-set-local 'org-done-keywords nil)
+ (org-set-local 'org-todo-heads nil)
+ (org-set-local 'org-todo-sets nil)
+ (org-set-local 'org-todo-log-states nil)
(let ((re (org-make-options-regexp
- '("CATEGORY" "SEQ_TODO" "PRI_TODO" "TYP_TODO"
- "STARTUP" "ARCHIVE" "TAGS" "LINK")))
+ '("CATEGORY" "SEQ_TODO" "TYP_TODO" "TODO" "COLUMNS"
+ "STARTUP" "ARCHIVE" "TAGS" "LINK" "PRIORITIES"
+ "CONSTANTS" "PROPERTY" "DRAWERS")))
(splitre "[ \t]+")
- kwds int key value cat arch tags links)
+ kwds kws0 kwsa key log value cat arch tags const links hw dws
+ tail sep kws1 prio props drawers)
(save-excursion
(save-restriction
(widen)
((equal key "CATEGORY")
(if (string-match "[ \t]+$" value)
(setq value (replace-match "" t t value)))
- (setq cat (intern value)))
- ((equal key "SEQ_TODO")
- (setq int 'sequence
- kwds (append kwds (org-split-string value splitre))))
- ((equal key "PRI_TODO")
- (setq int 'priority
- kwds (append kwds (org-split-string value splitre))))
+ (setq cat value))
+ ((member key '("SEQ_TODO" "TODO"))
+ (push (cons 'sequence (org-split-string value splitre)) kwds))
((equal key "TYP_TODO")
- (setq int 'type
- kwds (append kwds (org-split-string value splitre))))
+ (push (cons 'type (org-split-string value splitre)) kwds))
((equal key "TAGS")
(setq tags (append tags (org-split-string value splitre))))
+ ((equal key "COLUMNS")
+ (org-set-local 'org-columns-default-format value))
((equal key "LINK")
(when (string-match "^\\(\\S-+\\)[ \t]+\\(.+\\)" value)
(push (cons (match-string 1 value)
(org-trim (match-string 2 value)))
links)))
+ ((equal key "PRIORITIES")
+ (setq prio (org-split-string value " +")))
+ ((equal key "PROPERTY")
+ (when (string-match "\\(\\S-+\\)\\s-+\\(.*\\)" value)
+ (push (cons (match-string 1 value) (match-string 2 value))
+ props)))
+ ((equal key "DRAWERS")
+ (setq drawers (org-split-string value splitre)))
+ ((equal key "CONSTANTS")
+ (setq const (append const (org-split-string value splitre))))
((equal key "STARTUP")
(let ((opts (org-split-string value splitre))
l var val)
- (while (setq l (assoc (pop opts) org-startup-options))
- (setq var (nth 1 l) val (nth 2 l))
- (if (not (nth 3 l))
- (set (make-local-variable var) val)
- (if (not (listp (symbol-value var)))
- (set (make-local-variable var) nil))
- (set (make-local-variable var) (symbol-value var))
- (add-to-list var val)))))
+ (while (setq l (pop opts))
+ (when (setq l (assoc l org-startup-options))
+ (setq var (nth 1 l) val (nth 2 l))
+ (if (not (nth 3 l))
+ (set (make-local-variable var) val)
+ (if (not (listp (symbol-value var)))
+ (set (make-local-variable var) nil))
+ (set (make-local-variable var) (symbol-value var))
+ (add-to-list var val))))))
((equal key "ARCHIVE")
(string-match " *$" value)
(setq arch (replace-match "" t t value))
(remove-text-properties 0 (length arch)
'(face t fontified t) arch)))
)))
- (and cat (org-set-local 'org-category cat))
- (and kwds (org-set-local 'org-todo-keywords kwds))
+ (when cat
+ (org-set-local 'org-category (intern cat))
+ (push (cons "CATEGORY" cat) props))
+ (when prio
+ (if (< (length prio) 3) (setq prio '("A" "C" "B")))
+ (setq prio (mapcar 'string-to-char prio))
+ (org-set-local 'org-highest-priority (nth 0 prio))
+ (org-set-local 'org-lowest-priority (nth 1 prio))
+ (org-set-local 'org-default-priority (nth 2 prio)))
+ (and props (org-set-local 'org-local-properties (nreverse props)))
+ (and drawers (org-set-local 'org-drawers drawers))
(and arch (org-set-local 'org-archive-location arch))
- (and int (org-set-local 'org-todo-interpretation int))
(and links (setq org-link-abbrev-alist-local (nreverse links)))
+ ;; Process the TODO keywords
+ (unless kwds
+ ;; Use the global values as if they had been given locally.
+ (setq kwds (default-value 'org-todo-keywords))
+ (if (stringp (car kwds))
+ (setq kwds (list (cons org-todo-interpretation
+ (default-value 'org-todo-keywords)))))
+ (setq kwds (reverse kwds)))
+ (setq kwds (nreverse kwds))
+ (let (inter kws kw)
+ (while (setq kws (pop kwds))
+ (setq inter (pop kws) sep (member "|" kws)
+ kws0 (delete "|" (copy-sequence kws))
+ kwsa nil
+ kws1 (mapcar
+ (lambda (x)
+ ;; 1 2
+ (if (string-match "^\\(.*?\\)\\(?:(\\([^!@/]\\)?.*?)\\)?$" x)
+ (progn
+ (setq kw (match-string 1 x)
+ key (and (match-end 2) (match-string 2 x))
+ log (org-extract-log-state-settings x))
+ (push (cons kw (and key (string-to-char key))) kwsa)
+ (and log (push log org-todo-log-states))
+ kw)
+ (error "Invalid TODO keyword %s" x)))
+ kws0)
+ kwsa (if kwsa (append '((:startgroup))
+ (nreverse kwsa)
+ '((:endgroup))))
+ hw (car kws1)
+ dws (if sep (org-remove-keyword-keys (cdr sep)) (last kws1))
+ tail (list inter hw (car dws) (org-last dws)))
+ (add-to-list 'org-todo-heads hw 'append)
+ (push kws1 org-todo-sets)
+ (setq org-done-keywords (append org-done-keywords dws nil))
+ (setq org-todo-key-alist (append org-todo-key-alist kwsa))
+ (mapc (lambda (x) (push (cons x tail) org-todo-kwd-alist)) kws1)
+ (setq org-todo-keywords-1 (append org-todo-keywords-1 kws1 nil)))
+ (setq org-todo-sets (nreverse org-todo-sets)
+ org-todo-kwd-alist (nreverse org-todo-kwd-alist)
+ org-todo-key-trigger (delq nil (mapcar 'cdr org-todo-key-alist))
+ org-todo-key-alist (org-assign-fast-keys org-todo-key-alist)))
+ ;; Process the constants
+ (when const
+ (let (e cst)
+ (while (setq e (pop const))
+ (if (string-match "^\\([a-zA-Z0][_a-zA-Z0-9]*\\)=\\(.*\\)" e)
+ (push (cons (match-string 1 e) (match-string 2 e)) cst)))
+ (setq org-table-formula-constants-local cst)))
+
+ ;; Process the tags.
(when tags
(let (e tgs)
(while (setq e (pop tags))
(cond
((equal e "{") (push '(:startgroup) tgs))
((equal e "}") (push '(:endgroup) tgs))
- ((string-match "^\\([0-9a-zA-Z_@]+\\)(\\(.\\))$" e)
+ ((string-match (org-re "^\\([[:alnum:]_@]+\\)(\\(.\\))$") e)
(push (cons (match-string 1 e)
(string-to-char (match-string 2 e)))
tgs))
(push e org-tag-alist))))))
;; Compute the regular expressions and other local variables
- (setq org-todo-kwd-priority-p (equal org-todo-interpretation 'priority)
- org-todo-kwd-max-priority (1- (length org-todo-keywords))
- org-ds-keyword-length (+ 2 (max (length org-deadline-string)
+ (if (not org-done-keywords)
+ (setq org-done-keywords (list (org-last org-todo-keywords-1))))
+ (setq org-ds-keyword-length (+ 2 (max (length org-deadline-string)
(length org-scheduled-string)))
- org-done-string
- (nth (1- (length org-todo-keywords)) org-todo-keywords)
+ org-drawer-regexp
+ (concat "^[ \t]*:\\("
+ (mapconcat 'regexp-quote org-drawers "\\|")
+ "\\):[ \t]*$")
+ org-not-done-keywords
+ (org-delete-all org-done-keywords (copy-sequence org-todo-keywords-1))
org-todo-regexp
- (concat "\\<\\(" (mapconcat 'regexp-quote org-todo-keywords
+ (concat "\\<\\(" (mapconcat 'regexp-quote org-todo-keywords-1
"\\|") "\\)\\>")
org-not-done-regexp
(concat "\\<\\("
- (mapconcat 'regexp-quote
- (nreverse (cdr (reverse org-todo-keywords)))
- "\\|")
+ (mapconcat 'regexp-quote org-not-done-keywords "\\|")
"\\)\\>")
org-todo-line-regexp
- (concat "^\\(\\*+\\)[ \t]*\\(?:\\("
- (mapconcat 'regexp-quote org-todo-keywords "\\|")
- "\\)\\>\\)? *\\(.*\\)")
+ (concat "^\\(\\*+\\)[ \t]+\\(?:\\("
+ (mapconcat 'regexp-quote org-todo-keywords-1 "\\|")
+ "\\)\\>\\)?[ \t]*\\(.*\\)")
+ org-complex-heading-regexp
+ (concat "^\\(\\*+\\)\\(?:[ \t]+\\("
+ (mapconcat 'regexp-quote org-todo-keywords-1 "\\|")
+ "\\)\\>\\)?\\(?:[ \t]*\\(\\[#.\\]\\)\\)?[ \t]*\\(.*?\\)"
+ "\\(?:[ \t]+\\(:[[:alnum:]_@:]+:\\)\\)?[ \t]*$")
org-nl-done-regexp
- (concat "[\r\n]\\*+[ \t]+" org-done-string "\\>")
+ (concat "\n\\*+[ \t]+"
+ "\\(?:" (mapconcat 'regexp-quote org-done-keywords "\\|")
+ "\\)" "\\>")
org-todo-line-tags-regexp
- (concat "^\\(\\*+\\)[ \t]*\\(?:\\("
- (mapconcat 'regexp-quote org-todo-keywords "\\|")
- "\\)\\>\\)? *\\(.*?\\([ \t]:[a-zA-Z0-9:_@]+:[ \t]*\\)?$\\)")
- org-looking-at-done-regexp (concat "^" org-done-string "\\>")
+ (concat "^\\(\\*+\\)[ \t]+\\(?:\\("
+ (mapconcat 'regexp-quote org-todo-keywords-1 "\\|")
+ (org-re
+ "\\)\\>\\)? *\\(.*?\\([ \t]:[[:alnum:]:_@]+:[ \t]*\\)?$\\)"))
+ org-looking-at-done-regexp
+ (concat "^" "\\(?:"
+ (mapconcat 'regexp-quote org-done-keywords "\\|") "\\)"
+ "\\>")
org-deadline-regexp (concat "\\<" org-deadline-string)
org-deadline-time-regexp
(concat "\\<" org-deadline-string " *<\\([^>]+\\)>")
org-keyword-time-not-clock-regexp
(concat "\\<\\(" org-scheduled-string
"\\|" org-deadline-string
- "\\|" org-closed-string "\\)"
+ "\\|" org-closed-string
+ "\\)"
" *[[<]\\([^]>]+\\)[]>]")
org-maybe-keyword-time-regexp
(concat "\\(\\<\\(" org-scheduled-string
"\\|" org-deadline-string
"\\|" org-closed-string
"\\|" org-clock-string "\\)\\)?"
- " *\\([[<][0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}[^]\r\n>]*?[]>]\\)"))
-
+ " *\\([[<][0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} [^]\r\n>]*?[]>]\\|<%%([^\r\n>]*>\\)")
+ org-planning-or-clock-line-re
+ (concat "\\(?:^[ \t]*\\(" org-scheduled-string
+ "\\|" org-deadline-string
+ "\\|" org-closed-string "\\|" org-clock-string
+ "\\)\\>\\)")
+ )
+ (org-compute-latex-and-specials-regexp)
(org-set-font-lock-defaults)))
+(defun org-extract-log-state-settings (x)
+ "Extract the log state setting from a TODO keyword string.
+This will extract info from a string like \"WAIT(w@/!)\"."
+ (let (kw key log1 log2)
+ (when (string-match "^\\(.*?\\)\\(?:(\\([^!@/]\\)?\\([!@]\\)?\\(?:/\\([!@]\\)\\)?)\\)?$" x)
+ (setq kw (match-string 1 x)
+ key (and (match-end 2) (match-string 2 x))
+ log1 (and (match-end 3) (match-string 3 x))
+ log2 (and (match-end 4) (match-string 4 x)))
+ (and (or log1 log2)
+ (list kw
+ (and log1 (if (equal log1 "!") 'time 'note))
+ (and log2 (if (equal log2 "!") 'time 'note)))))))
+
+(defun org-remove-keyword-keys (list)
+ "Remove a pair of parenthesis at the end of each string in LIST."
+ (mapcar (lambda (x)
+ (if (string-match "(.*)$" x)
+ (substring x 0 (match-beginning 0))
+ x))
+ list))
+
+;; FIXME: this could be done much better, using second characters etc.
+(defun org-assign-fast-keys (alist)
+ "Assign fast keys to a keyword-key alist.
+Respect keys that are already there."
+ (let (new e k c c1 c2 (char ?a))
+ (while (setq e (pop alist))
+ (cond
+ ((equal e '(:startgroup)) (push e new))
+ ((equal e '(:endgroup)) (push e new))
+ (t
+ (setq k (car e) c2 nil)
+ (if (cdr e)
+ (setq c (cdr e))
+ ;; automatically assign a character.
+ (setq c1 (string-to-char
+ (downcase (substring
+ k (if (= (string-to-char k) ?@) 1 0)))))
+ (if (or (rassoc c1 new) (rassoc c1 alist))
+ (while (or (rassoc char new) (rassoc char alist))
+ (setq char (1+ char)))
+ (setq c2 c1))
+ (setq c (or c2 char)))
+ (push (cons k c) new))))
+ (nreverse new)))
;;; Some variables ujsed in various places
"Function to be called when `C-c C-c' is used.
This is for getting out of special buffers like remember.")
-;;; Foreign variables, to inform the compiler
-
-;; XEmacs only
-(defvar outline-mode-menu-heading)
-(defvar outline-mode-menu-show)
-(defvar outline-mode-menu-hide)
-(defvar zmacs-regions) ; XEmacs regions
-;; Emacs only
-(defvar mark-active)
-
-;; Packages that org-mode interacts with
-(defvar calc-embedded-close-formula)
-(defvar calc-embedded-open-formula)
-(defvar font-lock-unfontify-region-function)
-(defvar org-goto-start-pos)
-(defvar vm-message-pointer)
-(defvar vm-folder-directory)
-(defvar wl-summary-buffer-elmo-folder)
-(defvar wl-summary-buffer-folder-name)
-(defvar gnus-other-frame-object)
-(defvar gnus-group-name)
-(defvar gnus-article-current)
-(defvar w3m-current-url)
-(defvar w3m-current-title)
-(defvar mh-progs)
-(defvar mh-current-folder)
-(defvar mh-show-folder-buffer)
-(defvar mh-index-folder)
-(defvar mh-searcher)
-(defvar calendar-mode-map)
-(defvar Info-current-file)
-(defvar Info-current-node)
-(defvar texmathp-why)
-(defvar remember-save-after-remembering)
-(defvar remember-data-file)
-(defvar annotation) ; from remember.el, dynamically scoped in `remember-mode'
-(defvar initial) ; from remember.el, dynamically scoped in `remember-mode'
-(defvar org-latex-regexps)
-
-(defvar original-date) ; dynamically scoped in calendar.el does scope this
;; FIXME: Occasionally check by commenting these, to make sure
;; no other functions uses these, forgetting to let-bind them.
(defvar date)
(defvar description)
-
;; Defined somewhere in this file, but used before definition.
(defvar orgtbl-mode-menu) ; defined when orgtbl mode get initialized
+(defvar org-agenda-buffer-name)
(defvar org-agenda-undo-list)
(defvar org-agenda-pending-undo-list)
(defvar org-agenda-overriding-header)
(defvar org-org-menu)
(defvar org-tbl-menu)
(defvar org-agenda-keymap)
-(defvar org-category-table)
;;;; Emacs/XEmacs compatibility
nil
(if (featurep 'xemacs)
(and zmacs-regions (region-active-p))
- (and transient-mark-mode mark-active))))
+ (if (fboundp 'use-region-p)
+ (use-region-p)
+ (and transient-mark-mode mark-active))))) ; Emacs 22 and before
;; Invisibility compatibility
(defvar org-mode-hook nil)
(defvar org-inhibit-startup nil) ; Dynamically-scoped param.
(defvar org-agenda-keep-modes nil) ; Dynamically-scoped param.
-
+(defvar org-table-buffer-is-an nil)
+(defconst org-outline-regexp "\\*+ ")
;;;###autoload
(define-derived-mode org-mode outline-mode "Org"
(org-add-to-invisibility-spec '(org-cwidth))
(when (featurep 'xemacs)
(org-set-local 'line-move-ignore-invisible t))
- (setq outline-regexp "\\*+")
- ;;(setq outline-regexp "\\(?:\\*+\\|[ \t]*\\(?:[-+*]\\|[0-9]+[.)]\\) \\)")
- (setq outline-level 'org-outline-level)
- (when (and org-ellipsis (stringp org-ellipsis)
- (fboundp 'set-display-table-slot) (boundp 'buffer-display-table))
+ (org-set-local 'outline-regexp org-outline-regexp)
+ (org-set-local 'outline-level 'org-outline-level)
+ (when (and org-ellipsis
+ (fboundp 'set-display-table-slot) (boundp 'buffer-display-table)
+ (fboundp 'make-glyph-code))
(unless org-display-table
(setq org-display-table (make-display-table)))
- (set-display-table-slot org-display-table
- 4 (string-to-vector org-ellipsis))
+ (set-display-table-slot
+ org-display-table 4
+ (vconcat (mapcar
+ (lambda (c) (make-glyph-code c (and (not (stringp org-ellipsis))
+ org-ellipsis)))
+ (if (stringp org-ellipsis) org-ellipsis "..."))))
(setq buffer-display-table org-display-table))
(org-set-regexps-and-options)
;; Calc embedded
(org-set-local 'calc-embedded-open-mode "# ")
(modify-syntax-entry ?# "<")
+ (modify-syntax-entry ?@ "w")
(if org-startup-truncated (setq truncate-lines t))
(org-set-local 'font-lock-unfontify-region-function
'org-unfontify-region)
(org-add-hook 'kill-buffer-hook 'org-check-running-clock nil 'local)
;; Paragraphs and auto-filling
(org-set-autofill-regexps)
+ (setq indent-line-function 'org-indent-line-function)
(org-update-radio-target-regexp)
;; Comment characters
; (org-set-local 'comment-start "#") ;; FIXME: this breaks wrapping
(org-set-local 'comment-padding " ")
+ ;; Align options lines
+ (org-set-local
+ 'align-mode-rules-list
+ '((org-in-buffer-settings
+ (regexp . "^#\\+[A-Z_]+:\\(\\s-*\\)\\S-+")
+ (modes . '(org-mode)))))
+
+ ;; Imenu
+ (org-set-local 'imenu-create-index-function
+ 'org-imenu-get-tree)
+
;; Make isearch reveal context
(if (or (featurep 'xemacs)
(not (boundp 'outline-isearch-open-invisible-function)))
(if (and org-insert-mode-line-in-empty-file
(interactive-p)
(= (point-min) (point-max)))
- (insert " -*- mode: org -*-\n\n"))
+ (insert "# -*- mode: org -*-\n\n"))
(unless org-inhibit-startup
(when org-startup-align-all-tables
(let ((bmp (buffer-modified-p)))
(org-table-map-tables 'org-table-align)
(set-buffer-modified-p bmp)))
+ (org-cycle-hide-drawers 'all)
(cond
((eq org-startup-folded t)
(org-cycle '(4)))
(let ((this-command 'org-cycle) (last-command 'org-cycle))
(org-cycle '(4)) (org-cycle '(4)))))))
+(put 'org-mode 'flyspell-mode-predicate 'org-mode-flyspell-verify)
+
(defsubst org-call-with-arg (command arg)
"Call COMMAND interactively, but pretend prefix are was ARG."
(let ((current-prefix-arg arg)) (call-interactively command)))
(defsubst org-current-line (&optional pos)
(save-excursion
(and pos (goto-char pos))
+ ;; works also in narrowed buffer, because we start at 1, not point-min
(+ (if (bolp) 1 0) (count-lines 1 (point)))))
(defun org-current-time ()
"Current time, possibly rounded to `org-time-stamp-rounding-minutes'."
- (if (> org-time-stamp-rounding-minutes 0)
- (let ((r org-time-stamp-rounding-minutes)
+ (if (> (car org-time-stamp-rounding-minutes) 1)
+ (let ((r (car org-time-stamp-rounding-minutes))
(time (decode-time)))
(apply 'encode-time
(append (list 0 (* r (floor (+ .5 (/ (float (nth 1 time)) r)))))
;;;; Font-Lock stuff, including the activators
(defvar org-mouse-map (make-sparse-keymap))
-(define-key org-mouse-map
+(org-defkey org-mouse-map
(if (featurep 'xemacs) [button2] [mouse-2]) 'org-open-at-mouse)
-(define-key org-mouse-map
+(org-defkey org-mouse-map
(if (featurep 'xemacs) [button3] [mouse-3]) 'org-find-file-at-mouse)
(when org-mouse-1-follows-link
- (define-key org-mouse-map [follow-link] 'mouse-face))
+ (org-defkey org-mouse-map [follow-link] 'mouse-face))
(when org-tab-follows-link
- (define-key org-mouse-map [(tab)] 'org-open-at-point)
- (define-key org-mouse-map "\C-i" 'org-open-at-point))
+ (org-defkey org-mouse-map [(tab)] 'org-open-at-point)
+ (org-defkey org-mouse-map "\C-i" 'org-open-at-point))
(when org-return-follows-link
- (define-key org-mouse-map [(return)] 'org-open-at-point)
- (define-key org-mouse-map "\C-m" 'org-open-at-point))
+ (org-defkey org-mouse-map [(return)] 'org-open-at-point)
+ (org-defkey org-mouse-map "\C-m" 'org-open-at-point))
(require 'font-lock)
(defconst org-non-link-chars "]\t\n\r<>")
-(defconst org-link-types '("https?" "ftp" "mailto" "file" "news" "bbdb" "vm"
- "wl" "mhe" "rmail" "gnus" "shell" "info" "elisp"))
-(defconst org-link-re-with-space
- (concat
- "<?\\(" (mapconcat 'identity org-link-types "\\|") "\\):"
- "\\([^" org-non-link-chars " ]"
- "[^" org-non-link-chars "]*"
- "[^" org-non-link-chars " ]\\)>?")
+(defvar org-link-types '("http" "https" "ftp" "mailto" "file" "news" "bbdb" "vm"
+ "wl" "mhe" "rmail" "gnus" "shell" "info" "elisp" "message"))
+(defvar org-link-re-with-space nil
"Matches a link with spaces, optional angular brackets around it.")
-
-(defconst org-link-re-with-space2
- (concat
- "<?\\(" (mapconcat 'identity org-link-types "\\|") "\\):"
- "\\([^" org-non-link-chars " ]"
- "[^]\t\n\r]*"
- "[^" org-non-link-chars " ]\\)>?")
+(defvar org-link-re-with-space2 nil
"Matches a link with spaces, optional angular brackets around it.")
-
-(defconst org-angle-link-re
- (concat
- "<\\(" (mapconcat 'identity org-link-types "\\|") "\\):"
- "\\([^" org-non-link-chars " ]"
- "[^" org-non-link-chars "]*"
- "\\)>")
+(defvar org-angle-link-re nil
"Matches link with angular brackets, spaces are allowed.")
-(defconst org-plain-link-re
- (concat
- "\\(" (mapconcat 'identity org-link-types "\\|") "\\):"
- "\\([^]\t\n\r<>,;() ]+\\)")
+(defvar org-plain-link-re nil
"Matches plain link, without spaces.")
-
-(defconst org-bracket-link-regexp
- "\\[\\[\\([^]]+\\)\\]\\(\\[\\([^]]+\\)\\]\\)?\\]"
+(defvar org-bracket-link-regexp nil
"Matches a link in double brackets.")
-
-(defconst org-bracket-link-analytic-regexp
- (concat
- "\\[\\["
- "\\(\\(" (mapconcat 'identity org-link-types "\\|") "\\):\\)?"
- "\\([^]]+\\)"
- "\\]"
- "\\(\\[" "\\([^]]+\\)" "\\]\\)?"
- "\\]"))
-; 1: http:
-; 2: http
-; 3: path
-; 4: [desc]
-; 5: desc
-
-(defconst org-any-link-re
- (concat "\\(" org-bracket-link-regexp "\\)\\|\\("
- org-angle-link-re "\\)\\|\\("
- org-plain-link-re "\\)")
+(defvar org-bracket-link-analytic-regexp nil
+ "Regular expression used to analyze links.
+Here is what the match groups contain after a match:
+1: http:
+2: http
+3: path
+4: [desc]
+5: desc")
+(defvar org-any-link-re nil
"Regular expression matching any link.")
-(defconst org-ts-lengths
- (cons (length (format-time-string (car org-time-stamp-formats)))
- (length (format-time-string (cdr org-time-stamp-formats))))
- "This holds the lengths of the two different time formats.")
-(defconst org-ts-regexp "<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}[^\r\n>]*?\\)>"
+(defun org-make-link-regexps ()
+ "Update the link regular expressions.
+This should be called after the variable `org-link-types' has changed."
+ (setq org-link-re-with-space
+ (concat
+ "<?\\(" (mapconcat 'identity org-link-types "\\|") "\\):"
+ "\\([^" org-non-link-chars " ]"
+ "[^" org-non-link-chars "]*"
+ "[^" org-non-link-chars " ]\\)>?")
+ org-link-re-with-space2
+ (concat
+ "<?\\(" (mapconcat 'identity org-link-types "\\|") "\\):"
+ "\\([^" org-non-link-chars " ]"
+ "[^]\t\n\r]*"
+ "[^" org-non-link-chars " ]\\)>?")
+ org-angle-link-re
+ (concat
+ "<\\(" (mapconcat 'identity org-link-types "\\|") "\\):"
+ "\\([^" org-non-link-chars " ]"
+ "[^" org-non-link-chars "]*"
+ "\\)>")
+ org-plain-link-re
+ (concat
+ "\\<\\(" (mapconcat 'identity org-link-types "\\|") "\\):"
+ "\\([^]\t\n\r<>() ]+[^]\t\n\r<>,.;() ]\\)")
+ org-bracket-link-regexp
+ "\\[\\[\\([^][]+\\)\\]\\(\\[\\([^][]+\\)\\]\\)?\\]"
+ org-bracket-link-analytic-regexp
+ (concat
+ "\\[\\["
+ "\\(\\(" (mapconcat 'identity org-link-types "\\|") "\\):\\)?"
+ "\\([^]]+\\)"
+ "\\]"
+ "\\(\\[" "\\([^]]+\\)" "\\]\\)?"
+ "\\]")
+ org-any-link-re
+ (concat "\\(" org-bracket-link-regexp "\\)\\|\\("
+ org-angle-link-re "\\)\\|\\("
+ org-plain-link-re "\\)")))
+
+(org-make-link-regexps)
+
+(defconst org-ts-regexp "<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} [^\r\n>]*?\\)>"
"Regular expression for fast time stamp matching.")
-(defconst org-ts-regexp-both "[[<]\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}[^\r\n>]*?\\)[]>]"
+(defconst org-ts-regexp-both "[[<]\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} [^\r\n>]*?\\)[]>]"
"Regular expression for fast time stamp matching.")
-(defconst org-ts-regexp1 "\\(\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\)\\([^]0-9>\r\n]*\\)\\(\\([0-9]\\{2\\}\\):\\([0-9]\\{2\\}\\)\\)?\\)"
+(defconst org-ts-regexp0 "\\(\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\) *\\([^]-+0-9>\r\n ]*\\)\\( \\([0-9]\\{2\\}\\):\\([0-9]\\{2\\}\\)\\)?\\)"
+ "Regular expression matching time strings for analysis.
+This one does not require the space after the date, so it can be used
+on a string that terminates immediately after the date.")
+(defconst org-ts-regexp1 "\\(\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\) +\\([^]-+0-9>\r\n ]*\\)\\( \\([0-9]\\{2\\}\\):\\([0-9]\\{2\\}\\)\\)?\\)"
"Regular expression matching time strings for analysis.")
-(defconst org-ts-regexp2 (concat "<" org-ts-regexp1 ">")
+(defconst org-ts-regexp2 (concat "<" org-ts-regexp1 "[^>\n]\\{0,16\\}>")
"Regular expression matching time stamps, with groups.")
-(defconst org-ts-regexp3 (concat "[[<]" org-ts-regexp1 "[]>]")
+(defconst org-ts-regexp3 (concat "[[<]" org-ts-regexp1 "[^]>\n]\\{0,16\\}[]>]")
"Regular expression matching time stamps (also [..]), with groups.")
(defconst org-tr-regexp (concat org-ts-regexp "--?-?" org-ts-regexp)
"Regular expression matching a time stamp range.")
(defun org-do-emphasis-faces (limit)
"Run through the buffer and add overlays to links."
- (if (re-search-forward org-emph-re limit t)
- (progn
- (font-lock-prepend-text-property (match-beginning 2) (match-end 2)
- 'face
- (nth 1 (assoc (match-string 3)
- org-emphasis-alist)))
- (add-text-properties (match-beginning 2) (match-end 2)
- '(font-lock-multiline t))
- (backward-char 1)
- t)))
+ (let (rtn)
+ (while (and (not rtn) (re-search-forward org-emph-re limit t))
+ (if (not (= (char-after (match-beginning 3))
+ (char-after (match-beginning 4))))
+ (progn
+ (setq rtn t)
+ (font-lock-prepend-text-property (match-beginning 2) (match-end 2)
+ 'face
+ (nth 1 (assoc (match-string 3)
+ org-emphasis-alist)))
+ (add-text-properties (match-beginning 2) (match-end 2)
+ '(font-lock-multiline t))
+ (when org-hide-emphasis-markers
+ (add-text-properties (match-end 4) (match-beginning 5)
+ '(invisible org-link))
+ (add-text-properties (match-beginning 3) (match-end 3)
+ '(invisible org-link)))))
+ (backward-char 1))
+ rtn))
-(defun org-activate-plain-links (limit)
- "Run through the buffer and add overlays to links."
- (if (re-search-forward org-plain-link-re limit t)
- (progn
- (add-text-properties (match-beginning 0) (match-end 0)
- (list 'mouse-face 'highlight
- 'rear-nonsticky t
- 'keymap org-mouse-map
- ))
+(defun org-emphasize (&optional char)
+ "Insert or change an emphasis, i.e. a font like bold or italic.
+If there is an active region, change that region to a new emphasis.
+If there is no region, just insert the marker characters and position
+the cursor between them.
+CHAR should be either the marker character, or the first character of the
+HTML tag associated with that emphasis. If CHAR is a space, the means
+to remove the emphasis of the selected region.
+If char is not given (for example in an interactive call) it
+will be prompted for."
+ (interactive)
+ (let ((eal org-emphasis-alist) e det
+ (erc org-emphasis-regexp-components)
+ (prompt "")
+ (string "") beg end move tag c s)
+ (if (org-region-active-p)
+ (setq beg (region-beginning) end (region-end)
+ string (buffer-substring beg end))
+ (setq move t))
+
+ (while (setq e (pop eal))
+ (setq tag (car (org-split-string (nth 2 e) "[ <>/]+"))
+ c (aref tag 0))
+ (push (cons c (string-to-char (car e))) det)
+ (setq prompt (concat prompt (format " [%s%c]%s" (car e) c
+ (substring tag 1)))))
+ (unless char
+ (message "%s" (concat "Emphasis marker or tag:" prompt))
+ (setq char (read-char-exclusive)))
+ (setq char (or (cdr (assoc char det)) char))
+ (if (equal char ?\ )
+ (setq s "" move nil)
+ (unless (assoc (char-to-string char) org-emphasis-alist)
+ (error "No such emphasis marker: \"%c\"" char))
+ (setq s (char-to-string char)))
+ (while (and (> (length string) 1)
+ (equal (substring string 0 1) (substring string -1))
+ (assoc (substring string 0 1) org-emphasis-alist))
+ (setq string (substring string 1 -1)))
+ (setq string (concat s string s))
+ (if beg (delete-region beg end))
+ (unless (or (bolp)
+ (string-match (concat "[" (nth 0 erc) "\n]")
+ (char-to-string (char-before (point)))))
+ (insert " "))
+ (unless (string-match (concat "[" (nth 1 erc) "\n]")
+ (char-to-string (char-after (point))))
+ (insert " ") (backward-char 1))
+ (insert string)
+ (and move (backward-char 1))))
+
+(defconst org-nonsticky-props
+ '(mouse-face highlight keymap invisible intangible help-echo org-linked-text))
+
+
+(defun org-activate-plain-links (limit)
+ "Run through the buffer and add overlays to links."
+ (catch 'exit
+ (let (f)
+ (while (re-search-forward org-plain-link-re limit t)
+ (setq f (get-text-property (match-beginning 0) 'face))
+ (if (or (eq f 'org-tag)
+ (and (listp f) (memq 'org-tag f)))
+ nil
+ (add-text-properties (match-beginning 0) (match-end 0)
+ (list 'mouse-face 'highlight
+ 'rear-nonsticky org-nonsticky-props
+ 'keymap org-mouse-map
+ ))
+ (throw 'exit t))))))
+
+(defun org-activate-code (limit)
+ (if (re-search-forward "^[ \t]*\\(:.*\\)" limit t)
+ (unless (get-text-property (match-beginning 1) 'face)
+ (remove-text-properties (match-beginning 0) (match-end 0)
+ '(display t invisible t intangible t))
t)))
(defun org-activate-angle-links (limit)
(progn
(add-text-properties (match-beginning 0) (match-end 0)
(list 'mouse-face 'highlight
- 'rear-nonsticky t
+ 'rear-nonsticky org-nonsticky-props
'keymap org-mouse-map
))
t)))
;; but that requires another match, protecting match data,
;; a lot of overhead for font-lock.
(ip (org-maybe-intangible
- (list 'invisible 'org-link 'rear-nonsticky t
+ (list 'invisible 'org-link 'rear-nonsticky org-nonsticky-props
'keymap org-mouse-map 'mouse-face 'highlight
- 'help-echo help)))
- (vp (list 'rear-nonsticky t
+ 'font-lock-multiline t 'help-echo help)))
+ (vp (list 'rear-nonsticky org-nonsticky-props
'keymap org-mouse-map 'mouse-face 'highlight
- 'help-echo help)))
+ ' font-lock-multiline t 'help-echo help)))
;; We need to remove the invisible property here. Table narrowing
;; may have made some of this invisible.
(remove-text-properties (match-beginning 0) (match-end 0)
(progn
(add-text-properties (match-beginning 0) (match-end 0)
(list 'mouse-face 'highlight
- 'rear-nonsticky t
+ 'rear-nonsticky org-nonsticky-props
'keymap org-mouse-map))
(when org-display-custom-times
(if (match-end 3)
(defvar org-target-regexp "<<\\([^<>\n\r]+\\)>>"
"Regular expression matching a link target.")
(defvar org-radio-target-regexp "<<<\\([^<>\n\r]+\\)>>>"
- "Regular expression matching a link target.")
+ "Regular expression matching a radio target.")
+(defvar org-any-target-regexp "<<<?\\([^<>\n\r]+\\)>>>?" ; FIXME, not exact, would match <<<aaa>> as a radio target.
+ "Regular expression matching any target.")
(defun org-activate-target-links (limit)
"Run through the buffer and add overlays to target matches."
(progn
(add-text-properties (match-beginning 0) (match-end 0)
(list 'mouse-face 'highlight
- 'rear-nonsticky t
+ 'rear-nonsticky org-nonsticky-props
'keymap org-mouse-map
'help-echo "Radio target link"
'org-linked-text t))
(goto-char e)
t)))
+(defvar org-latex-and-specials-regexp nil
+ "Regular expression for highlighting export special stuff.")
+(defvar org-match-substring-regexp)
+(defvar org-match-substring-with-braces-regexp)
+(defvar org-export-html-special-string-regexps)
+
+(defun org-compute-latex-and-specials-regexp ()
+ "Compute regular expression for stuff treated specially by exporters."
+ (if (not org-highlight-latex-fragments-and-specials)
+ (org-set-local 'org-latex-and-specials-regexp nil)
+ (let*
+ ((matchers (plist-get org-format-latex-options :matchers))
+ (latexs (delq nil (mapcar (lambda (x) (if (member (car x) matchers) x))
+ org-latex-regexps)))
+ (options (org-combine-plists (org-default-export-plist)
+ (org-infile-export-plist)))
+ (org-export-with-sub-superscripts (plist-get options :sub-superscript))
+ (org-export-with-LaTeX-fragments (plist-get options :LaTeX-fragments))
+ (org-export-with-TeX-macros (plist-get options :TeX-macros))
+ (org-export-html-expand (plist-get options :expand-quoted-html))
+ (org-export-with-special-strings (plist-get options :special-strings))
+ (re-sub
+ (cond
+ ((equal org-export-with-sub-superscripts '{})
+ (list org-match-substring-with-braces-regexp))
+ (org-export-with-sub-superscripts
+ (list org-match-substring-regexp))
+ (t nil)))
+ (re-latex
+ (if org-export-with-LaTeX-fragments
+ (mapcar (lambda (x) (nth 1 x)) latexs)))
+ (re-macros
+ (if org-export-with-TeX-macros
+ (list (concat "\\\\"
+ (regexp-opt
+ (append (mapcar 'car org-html-entities)
+ (if (boundp 'org-latex-entities)
+ org-latex-entities nil))
+ 'words))) ; FIXME
+ ))
+ ;; (list "\\\\\\(?:[a-zA-Z]+\\)")))
+ (re-special (if org-export-with-special-strings
+ (mapcar (lambda (x) (car x))
+ org-export-html-special-string-regexps)))
+ (re-rest
+ (delq nil
+ (list
+ (if org-export-html-expand "@<[^>\n]+>")
+ ))))
+ (org-set-local
+ 'org-latex-and-specials-regexp
+ (mapconcat 'identity (append re-latex re-sub re-macros re-special
+ re-rest) "\\|")))))
+
+(defface org-latex-and-export-specials
+ (let ((font (cond ((assq :inherit custom-face-attributes)
+ '(:inherit underline))
+ (t '(:underline t)))))
+ `((((class grayscale) (background light))
+ (:foreground "DimGray" ,@font))
+ (((class grayscale) (background dark))
+ (:foreground "LightGray" ,@font))
+ (((class color) (background light))
+ (:foreground "SaddleBrown"))
+ (((class color) (background dark))
+ (:foreground "burlywood"))
+ (t (,@font))))
+ "Face used to highlight math latex and other special exporter stuff."
+ :group 'org-faces)
+
+(defun org-do-latex-and-special-faces (limit)
+ "Run through the buffer and add overlays to links."
+ (when org-latex-and-specials-regexp
+ (let (rtn d)
+ (while (and (not rtn) (re-search-forward org-latex-and-specials-regexp
+ limit t))
+ (if (not (memq (car-safe (get-text-property (1+ (match-beginning 0))
+ 'face))
+ '(org-code org-verbatim underline)))
+ (progn
+ (setq rtn t
+ d (cond ((member (char-after (1+ (match-beginning 0)))
+ '(?_ ?^)) 1)
+ (t 0)))
+ (font-lock-prepend-text-property
+ (+ d (match-beginning 0)) (match-end 0)
+ 'face 'org-latex-and-export-specials)
+ (add-text-properties (+ d (match-beginning 0)) (match-end 0)
+ '(font-lock-multiline t)))))
+ rtn)))
+
(defun org-restart-font-lock ()
"Restart font-lock-mode, to force refontification."
(when (and (boundp 'font-lock-mode) font-lock-mode)
"\\)\\>")))
(defun org-activate-tags (limit)
- (if (re-search-forward "[ \t]\\(:[A-Za-z_@0-9:]+:\\)[ \r\n]" limit t)
+ (if (re-search-forward (org-re "^\\*+.*[ \t]\\(:[[:alnum:]_@:]+:\\)[ \r\n]") limit t)
(progn
(add-text-properties (match-beginning 1) (match-end 1)
(list 'mouse-face 'highlight
- 'rear-nonsticky t
+ 'rear-nonsticky org-nonsticky-props
'keymap org-mouse-map))
t)))
-(defun org-font-lock-level ()
- (save-excursion
- (org-back-to-heading t)
- (- (match-end 0) (match-beginning 0))))
-
(defun org-outline-level ()
(save-excursion
(looking-at outline-regexp)
(if (match-beginning 1)
(+ (org-get-string-indentation (match-string 1)) 1000)
- (- (match-end 0) (match-beginning 0)))))
+ (1- (- (match-end 0) (match-beginning 0))))))
(defvar org-font-lock-keywords nil)
+(defconst org-property-re (org-re "^[ \t]*\\(:\\([[:alnum:]_]+\\):\\)[ \t]*\\(\\S-.*\\)")
+ "Regular expression matching a property line.")
+
(defun org-set-font-lock-defaults ()
(let* ((em org-fontify-emphasized-text)
(lk org-activate-links)
(org-font-lock-extra-keywords
- ;; Headlines
(list
- '("^\\(\\**\\)\\(\\*\\)\\(.*\\)" (1 (org-get-level-face 1))
+ ;; Headlines
+ '("^\\(\\**\\)\\(\\* \\)\\(.*\\)" (1 (org-get-level-face 1))
(2 (org-get-level-face 2)) (3 (org-get-level-face 3)))
+ ;; Table lines
'("^[ \t]*\\(\\(|\\|\\+-[-+]\\).*\\S-\\)"
- (1 'org-table))
+ (1 'org-table t))
+ ;; Table internals
+ '("^[ \t]*|\\(?:.*?|\\)? *\\(:?=[^|\n]*\\)" (1 'org-formula t))
+ '("^[ \t]*| *\\([#*]\\) *|" (1 'org-formula t))
+ '("^[ \t]*|\\( *\\([$!_^/]\\) *|.*\\)|" (1 'org-formula t))
+ ;; Drawers
+ (list org-drawer-regexp '(0 'org-special-keyword t))
+ (list "^[ \t]*:END:" '(0 'org-special-keyword t))
+ ;; Properties
+ (list org-property-re
+ '(1 'org-special-keyword t)
+ '(3 'org-property-value t))
+ (if org-format-transports-properties-p
+ '("| *\\(<[0-9]+>\\) *" (1 'org-formula t)))
;; Links
+ (if (memq 'tag lk) '(org-activate-tags (1 'org-tag prepend)))
(if (memq 'angle lk) '(org-activate-angle-links (0 'org-link t)))
(if (memq 'plain lk) '(org-activate-plain-links (0 'org-link t)))
(if (memq 'bracket lk) '(org-activate-bracket-links (0 'org-link t)))
(if (memq 'radio lk) '(org-activate-target-links (0 'org-link t)))
(if (memq 'date lk) '(org-activate-dates (0 'org-date t)))
- (if (memq 'tag lk) '(org-activate-tags (1 'org-tag prepend)))
+ '("^&?%%(.*\\|<%%([^>\n]*?>" (0 'org-sexp-date t))
'(org-hide-wide-columns (0 nil append))
;; TODO lines
- (list (concat "^\\*+[ \t]*" org-not-done-regexp)
- '(1 'org-todo t))
+ (list (concat "^\\*+[ \t]+" org-todo-regexp)
+ '(1 (org-get-todo-face 1) t))
+ ;; DONE
+ (if org-fontify-done-headline
+ (list (concat "^[*]+ +\\<\\("
+ (mapconcat 'regexp-quote org-done-keywords "\\|")
+ "\\)\\(.*\\)")
+ '(2 'org-headline-done t))
+ nil)
;; Priorities
- (list (concat "\\[#[A-Z]\\]") '(0 'org-special-keyword t))
+ (list (concat "\\[#[A-Z0-9]\\]") '(0 'org-special-keyword t))
;; Special keywords
- (list org-repeat-re '(0 'org-special-keyword t))
(list (concat "\\<" org-deadline-string) '(0 'org-special-keyword t))
(list (concat "\\<" org-scheduled-string) '(0 'org-special-keyword t))
(list (concat "\\<" org-closed-string) '(0 'org-special-keyword t))
(if (featurep 'xemacs)
'(org-do-emphasis-faces (0 nil append))
'(org-do-emphasis-faces)))
- ;; Checkboxes, similar to Frank Ruell's org-checklet.el
- '("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(\\[[ X]\\]\\)"
+ ;; Checkboxes
+ '("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(\\[[- X]\\]\\)"
2 'bold prepend)
(if org-provide-checkbox-statistics
'("\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
(0 (org-get-checkbox-statistics-face) t)))
+ (list (concat "^\\*+ \\(.*:" org-archive-tag ":.*\\)")
+ '(1 'org-archived prepend))
+ ;; Specials
+ '(org-do-latex-and-special-faces)
+ ;; Code
+ '(org-activate-code (1 'org-code t))
;; COMMENT
- (list (concat "^\\*+[ \t]*\\<\\(" org-comment-string
+ (list (concat "^\\*+[ \t]+\\<\\(" org-comment-string
"\\|" org-quote-string "\\)\\>")
'(1 'org-special-keyword t))
'("^#.*" (0 'font-lock-comment-face t))
- ;; DONE
- (if org-fontify-done-headline
- (list (concat "^[*]+ +\\<\\(" org-done-string "\\)\\(.*\\)\\>")
- '(1 'org-done t) '(2 'org-headline-done t))
- (list (concat "^[*]+ +\\<\\(" org-done-string "\\)\\>")
- '(1 'org-done t)))
- ;; Table stuff
- '("^[ \t]*\\(:.*\\)" (1 'org-table t))
- '("| *\\(:?=[^|\n]*\\)" (1 'org-formula t))
- '("^[ \t]*| *\\([#!$*_^]\\) *|" (1 'org-formula t))
- (if org-format-transports-properties-p
- '("| *\\(<[0-9]+>\\) *" (1 'org-formula t)))
- '("^\\*+ \\(.*:ARCHIVE:.*\\)" (1 'org-archived prepend))
)))
(setq org-font-lock-extra-keywords (delq nil org-font-lock-extra-keywords))
;; Now set the full font-lock-keywords
(defvar org-f nil)
(defun org-get-level-face (n)
"Get the right face for match N in font-lock matching of healdines."
- (setq org-l (- (match-end 2) (match-beginning 1)))
+ (setq org-l (- (match-end 2) (match-beginning 1) 1))
(if org-odd-levels-only (setq org-l (1+ (/ org-l 2))))
-; (setq org-f (nth (1- (% org-l org-n-levels)) org-level-faces))
- (setq org-f (nth (% (1- org-l) org-n-levels) org-level-faces))
+ (setq org-f (nth (% (1- org-l) org-n-level-faces) org-level-faces))
(cond
((eq n 1) (if org-hide-leading-stars 'org-hide org-f))
((eq n 2) org-f)
(t (if org-level-color-stars-only nil org-f))))
+(defun org-get-todo-face (kwd)
+ "Get the right face for a TODO keyword KWD.
+If KWD is a number, get the corresponding match group."
+ (if (numberp kwd) (setq kwd (match-string kwd)))
+ (or (cdr (assoc kwd org-todo-keyword-faces))
+ (and (member kwd org-done-keywords) 'org-done)
+ 'org-todo))
+
(defun org-unfontify-region (beg end &optional maybe_loudly)
"Remove fontification and activation overlays from links."
(font-lock-default-unfontify-region beg end)
deactivate-mark buffer-file-name buffer-file-truename)
(remove-text-properties beg end
'(mouse-face t keymap t org-linked-text t
- rear-nonsticky t
invisible t intangible t))))
;;;; Visibility cycling, including org-goto and indirect buffer
`indent-relative', like TAB normally does. See the option
`org-cycle-emulate-tab' for details.
-- Special case: if point is the beginning of the buffer and there is no
- headline in line 1, this function will act as if called with prefix arg."
+- Special case: if point is at the beginning of the buffer and there is
+ no headline in line 1, this function will act as if called with prefix arg.
+ But only if also the variable `org-cycle-global-at-bob' is t."
(interactive "P")
(let* ((outline-regexp
(if (and (org-mode-p) org-cycle-include-plain-lists)
- "\\(?:\\*+\\|\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) \\)"
+ "\\(?:\\*+ \\|\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) \\)"
outline-regexp))
(bob-special (and org-cycle-global-at-bob (bobp)
(not (looking-at outline-regexp))))
(setq org-cycle-global-status 'overview)
(run-hook-with-args 'org-cycle-hook 'overview))))
+ ((and org-drawers org-drawer-regexp
+ (save-excursion
+ (beginning-of-line 1)
+ (looking-at org-drawer-regexp)))
+ ;; Toggle block visibility
+ (org-flag-drawer
+ (not (get-char-property (match-end 0) 'invisible))))
+
((integerp arg)
;; Show-subtree, ARG levels up from here.
(save-excursion
(- (funcall outline-level) arg)))
(org-show-subtree)))
- ((save-excursion (beginning-of-line 1) (looking-at outline-regexp))
+ ((and (save-excursion (beginning-of-line 1) (looking-at outline-regexp))
+ (or (bolp) (not (eq org-cycle-emulate-tab 'exc-hl-bol))))
;; At a heading: rotate between three different views
(org-back-to-heading)
(let ((goal-column 0) eoh eol eos)
(beginning-of-line 2)) (setq eol (point)))
(outline-end-of-heading) (setq eoh (point))
(org-end-of-subtree t)
- (skip-chars-forward " \t\n")
- (beginning-of-line 1) ; in case this is an item
+ (unless (eobp)
+ (skip-chars-forward " \t\n")
+ (beginning-of-line 1) ; in case this is an item
+ )
(setq eos (1- (point))))
;; Find out what to do next and set `this-command'
(cond
((= eos eoh)
;; Nothing is hidden behind this heading
(message "EMPTY ENTRY")
- (setq org-cycle-subtree-status nil))
- ((>= eol eos)
+ (setq org-cycle-subtree-status nil)
+ (save-excursion
+ (goto-char eos)
+ (outline-next-heading)
+ (if (org-invisible-p) (org-flag-heading nil))))
+ ((or (>= eol eos)
+ (not (string-match "\\S-" (buffer-substring eol eos))))
;; Entire subtree is hidden in one line: open it
(org-show-entry)
(show-children)
(message "CHILDREN")
+ (save-excursion
+ (goto-char eos)
+ (outline-next-heading)
+ (if (org-invisible-p) (org-flag-heading nil)))
(setq org-cycle-subtree-status 'children)
(run-hook-with-args 'org-cycle-hook 'children))
((and (eq last-command this-command)
((org-try-cdlatex-tab))
+ ((and (eq org-cycle-emulate-tab 'exc-hl-bol)
+ (or (not (bolp))
+ (not (looking-at outline-regexp))))
+ (call-interactively (global-key-binding "\t")))
+
((if (and (memq org-cycle-emulate-tab '(white whitestart))
(save-excursion (beginning-of-line 1) (looking-at "[ \t]*"))
(or (and (eq org-cycle-emulate-tab 'white)
(>= (match-end 0) pos))))
t
(eq org-cycle-emulate-tab t))
- (if (and (looking-at "[ \n\r\t]")
- (string-match "^[ \t]*$" (buffer-substring
- (point-at-bol) (point))))
- (progn
- (beginning-of-line 1)
- (and (looking-at "[ \t]+") (replace-match ""))))
- (indent-relative))
+; (if (and (looking-at "[ \n\r\t]")
+; (string-match "^[ \t]*$" (buffer-substring
+; (point-at-bol) (point))))
+; (progn
+; (beginning-of-line 1)
+; (and (looking-at "[ \t]+") (replace-match ""))))
+ (call-interactively (global-key-binding "\t")))
(t (save-excursion
(org-back-to-heading)
first headline is not level one, then (hide-sublevels 1) gives confusing
results."
(interactive)
- (hide-sublevels (save-excursion
- (goto-char (point-min))
- (if (re-search-forward (concat "^" outline-regexp) nil t)
- (progn
- (goto-char (match-beginning 0))
- (funcall outline-level))
- 1))))
+ (let ((level (save-excursion
+ (goto-char (point-min))
+ (if (re-search-forward (concat "^" outline-regexp) nil t)
+ (progn
+ (goto-char (match-beginning 0))
+ (funcall outline-level))))))
+ (and level (hide-sublevels level))))
(defun org-content (&optional arg)
"Show all headlines in the buffer, like a table of contents.
This function is the default value of the hook `org-cycle-hook'."
(when (get-buffer-window (current-buffer))
(cond
- ((eq state 'overview) (org-first-headline-recenter 1))
+; ((eq state 'overview) (org-first-headline-recenter 1))
+; ((eq state 'overview) (org-beginning-of-line))
((eq state 'content) nil)
((eq state 'all) nil)
((eq state 'folded) nil)
((eq state 'children) (or (org-subtree-end-visible-p) (recenter 1)))
((eq state 'subtree) (or (org-subtree-end-visible-p) (recenter 1))))))
+(defun org-compact-display-after-subtree-move ()
+ (let (beg end)
+ (save-excursion
+ (if (org-up-heading-safe)
+ (progn
+ (hide-subtree)
+ (show-entry)
+ (show-children)
+ (org-cycle-show-empty-lines 'children)
+ (org-cycle-hide-drawers 'children))
+ (org-overview)))))
+
+(defun org-cycle-show-empty-lines (state)
+ "Show empty lines above all visible headlines.
+The region to be covered depends on STATE when called through
+`org-cycle-hook'. Lisp program can use t for STATE to get the
+entire buffer covered. Note that an empty line is only shown if there
+are at least `org-cycle-separator-lines' empty lines before the headeline."
+ (when (> org-cycle-separator-lines 0)
+ (save-excursion
+ (let* ((n org-cycle-separator-lines)
+ (re (cond
+ ((= n 1) "\\(\n[ \t]*\n\\*+\\) ")
+ ((= n 2) "^[ \t]*\\(\n[ \t]*\n\\*+\\) ")
+ (t (let ((ns (number-to-string (- n 2))))
+ (concat "^\\(?:[ \t]*\n\\)\\{" ns "," ns "\\}"
+ "[ \t]*\\(\n[ \t]*\n\\*+\\) ")))))
+ beg end)
+ (cond
+ ((memq state '(overview contents t))
+ (setq beg (point-min) end (point-max)))
+ ((memq state '(children folded))
+ (setq beg (point) end (progn (org-end-of-subtree t t)
+ (beginning-of-line 2)
+ (point)))))
+ (when beg
+ (goto-char beg)
+ (while (re-search-forward re end t)
+ (if (not (get-char-property (match-end 1) 'invisible))
+ (outline-flag-region
+ (match-beginning 1) (match-end 1) nil)))))))
+ ;; Never hide empty lines at the end of the file.
+ (save-excursion
+ (goto-char (point-max))
+ (outline-previous-heading)
+ (outline-end-of-heading)
+ (if (and (looking-at "[ \t\n]+")
+ (= (match-end 0) (point-max)))
+ (outline-flag-region (point) (match-end 0) nil))))
+
(defun org-subtree-end-visible-p ()
"Is the end of the current subtree visible?"
(pos-visible-in-window-p
(defvar org-goto-window-configuration nil)
(defvar org-goto-marker nil)
-(defvar org-goto-map (make-sparse-keymap))
-(let ((cmds '(isearch-forward isearch-backward)) cmd)
- (while (setq cmd (pop cmds))
- (substitute-key-definition cmd cmd org-goto-map global-map)))
-(define-key org-goto-map "\C-m" 'org-goto-ret)
-(define-key org-goto-map [(left)] 'org-goto-left)
-(define-key org-goto-map [(right)] 'org-goto-right)
-(define-key org-goto-map [(?q)] 'org-goto-quit)
-(define-key org-goto-map [(control ?g)] 'org-goto-quit)
-(define-key org-goto-map "\C-i" 'org-cycle)
-(define-key org-goto-map [(tab)] 'org-cycle)
-(define-key org-goto-map [(down)] 'outline-next-visible-heading)
-(define-key org-goto-map [(up)] 'outline-previous-visible-heading)
-(define-key org-goto-map "n" 'outline-next-visible-heading)
-(define-key org-goto-map "p" 'outline-previous-visible-heading)
-(define-key org-goto-map "f" 'outline-forward-same-level)
-(define-key org-goto-map "b" 'outline-backward-same-level)
-(define-key org-goto-map "u" 'outline-up-heading)
-(define-key org-goto-map "\C-c\C-n" 'outline-next-visible-heading)
-(define-key org-goto-map "\C-c\C-p" 'outline-previous-visible-heading)
-(define-key org-goto-map "\C-c\C-f" 'outline-forward-same-level)
-(define-key org-goto-map "\C-c\C-b" 'outline-backward-same-level)
-(define-key org-goto-map "\C-c\C-u" 'outline-up-heading)
-(let ((l '(1 2 3 4 5 6 7 8 9 0)))
- (while l (define-key org-goto-map (int-to-string (pop l)) 'digit-argument)))
+(defvar org-goto-map
+ (let ((map (make-sparse-keymap)))
+ (let ((cmds '(isearch-forward isearch-backward kill-ring-save set-mark-command mouse-drag-region universal-argument org-occur)) cmd)
+ (while (setq cmd (pop cmds))
+ (substitute-key-definition cmd cmd map global-map)))
+ (suppress-keymap map)
+ (org-defkey map "\C-m" 'org-goto-ret)
+ (org-defkey map [(return)] 'org-goto-ret)
+ (org-defkey map [(left)] 'org-goto-left)
+ (org-defkey map [(right)] 'org-goto-right)
+ (org-defkey map [(control ?g)] 'org-goto-quit)
+ (org-defkey map "\C-i" 'org-cycle)
+ (org-defkey map [(tab)] 'org-cycle)
+ (org-defkey map [(down)] 'outline-next-visible-heading)
+ (org-defkey map [(up)] 'outline-previous-visible-heading)
+ (if org-goto-auto-isearch
+ (if (fboundp 'define-key-after)
+ (define-key-after map [t] 'org-goto-local-auto-isearch)
+ nil)
+ (org-defkey map "q" 'org-goto-quit)
+ (org-defkey map "n" 'outline-next-visible-heading)
+ (org-defkey map "p" 'outline-previous-visible-heading)
+ (org-defkey map "f" 'outline-forward-same-level)
+ (org-defkey map "b" 'outline-backward-same-level)
+ (org-defkey map "u" 'outline-up-heading))
+ (org-defkey map "/" 'org-occur)
+ (org-defkey map "\C-c\C-n" 'outline-next-visible-heading)
+ (org-defkey map "\C-c\C-p" 'outline-previous-visible-heading)
+ (org-defkey map "\C-c\C-f" 'outline-forward-same-level)
+ (org-defkey map "\C-c\C-b" 'outline-backward-same-level)
+ (org-defkey map "\C-c\C-u" 'outline-up-heading)
+ map))
(defconst org-goto-help
-"Select a location to jump to, press RET
-\[Up]/[Down]=next/prev headline TAB=cycle visibility RET=select [Q]uit")
+"Browse buffer copy, to find location or copy text. Just type for auto-isearch.
+RET=jump to location [Q]uit and return to previous location
+\[Up]/[Down]=next/prev headline TAB=cycle visibility [/] org-occur")
-(defun org-goto ()
- "Go to a different location of the document, keeping current visibility.
+(defvar org-goto-start-pos) ; dynamically scoped parameter
-When you want to go to a different location in a document, the fastest way
-is often to fold the entire buffer and then dive into the tree. This
-method has the disadvantage, that the previous location will be folded,
+(defun org-goto (&optional alternative-interface)
+ "Look up a different location in the current file, keeping current visibility.
+
+When you want look-up or go to a different location in a document, the
+fastest way is often to fold the entire buffer and then dive into the tree.
+This method has the disadvantage, that the previous location will be folded,
which may not be what you want.
-This command works around this by showing a copy of the current buffer in
-overview mode. You can dive into the tree in that copy, to find the
-location you want to reach. When pressing RET, the command returns to the
-original buffer in which the visibility is still unchanged. It then jumps
-to the new location, making it and the headline hierarchy above it visible."
- (interactive)
- (let* ((org-goto-start-pos (point))
+This command works around this by showing a copy of the current buffer
+in an indirect buffer, in overview mode. You can dive into the tree in
+that copy, use org-occur and incremental search to find a location.
+When pressing RET or `Q', the command returns to the original buffer in
+which the visibility is still unchanged. After RET is will also jump to
+the location selected in the indirect buffer and expose the
+the headline hierarchy above."
+ (interactive "P")
+ (let* ((org-refile-targets '((nil . (:maxlevel . 10))))
+ (org-refile-use-outline-path t)
+ (interface
+ (if (not alternative-interface)
+ org-goto-interface
+ (if (eq org-goto-interface 'outline)
+ 'outline-path-completion
+ 'outline)))
+ (org-goto-start-pos (point))
(selected-point
- (org-get-location (current-buffer) org-goto-help)))
+ (if (eq interface 'outline)
+ (car (org-get-location (current-buffer) org-goto-help))
+ (nth 3 (org-refile-get-location "Goto: ")))))
(if selected-point
(progn
(org-mark-ring-push org-goto-start-pos)
(goto-char selected-point)
(if (or (org-invisible-p) (org-invisible-p2))
(org-show-context 'org-goto)))
- (error "Quit"))))
+ (message "Quit"))))
-(defvar org-selected-point nil) ; dynamically scoped parameter
+(defvar org-goto-selected-point nil) ; dynamically scoped parameter
+(defvar org-goto-exit-command nil) ; dynamically scoped parameter
+(defvar org-goto-local-auto-isearch-map) ; defined below
(defun org-get-location (buf help)
"Let the user select a location in the Org-mode buffer BUF.
This function uses a recursive edit. It returns the selected position
or nil."
- (let (org-selected-point)
+ (let ((isearch-mode-map org-goto-local-auto-isearch-map)
+ (isearch-hide-immediately nil)
+ (isearch-search-fun-function
+ (lambda () 'org-goto-local-search-forward-headings))
+ (org-goto-selected-point org-goto-exit-command))
(save-excursion
(save-window-excursion
(delete-other-windows)
- (switch-to-buffer (get-buffer-create "*org-goto*"))
+ (and (get-buffer "*org-goto*") (kill-buffer "*org-goto*"))
+ (switch-to-buffer
+ (condition-case nil
+ (make-indirect-buffer (current-buffer) "*org-goto*")
+ (error (make-indirect-buffer (current-buffer) "*org-goto*"))))
(with-output-to-temp-buffer "*Help*"
(princ help))
(shrink-window-if-larger-than-buffer (get-buffer-window "*Help*"))
(setq buffer-read-only nil)
- (erase-buffer)
- (insert-buffer-substring buf)
(let ((org-startup-truncated t)
- (org-startup-folded t)
+ (org-startup-folded nil)
(org-startup-align-all-tables nil))
- (org-mode))
+ (org-mode)
+ (org-overview))
(setq buffer-read-only t)
(if (and (boundp 'org-goto-start-pos)
(integer-or-marker-p org-goto-start-pos))
(goto-char (point-min)))
(org-beginning-of-line)
(message "Select location and press RET")
- ;; now we make sure that during selection, ony very few keys work
- ;; and that it is impossible to switch to another window.
- (let ((gm (current-global-map))
- (overriding-local-map org-goto-map))
- (unwind-protect
- (progn
- (use-global-map org-goto-map)
- (recursive-edit))
- (use-global-map gm)))))
+ (use-local-map org-goto-map)
+ (recursive-edit)
+ ))
(kill-buffer "*org-goto*")
- org-selected-point))
+ (cons org-goto-selected-point org-goto-exit-command)))
+
+(defvar org-goto-local-auto-isearch-map (make-sparse-keymap))
+(set-keymap-parent org-goto-local-auto-isearch-map isearch-mode-map)
+(define-key org-goto-local-auto-isearch-map "\C-i" 'isearch-other-control-char)
+(define-key org-goto-local-auto-isearch-map "\C-m" 'isearch-other-control-char)
+
+(defun org-goto-local-search-forward-headings (string bound noerror)
+ "Search and make sure that anu matches are in headlines."
+ (catch 'return
+ (while (search-forward string bound noerror)
+ (when (let ((context (mapcar 'car (save-match-data (org-context)))))
+ (and (member :headline context)
+ (not (member :tags context))))
+ (throw 'return (point))))))
+
+(defun org-goto-local-auto-isearch ()
+ "Start isearch."
+ (interactive)
+ (goto-char (point-min))
+ (let ((keys (this-command-keys)))
+ (when (eq (lookup-key isearch-mode-map keys) 'isearch-printing-char)
+ (isearch-mode t)
+ (isearch-process-search-char (string-to-char keys)))))
(defun org-goto-ret (&optional arg)
"Finish `org-goto' by going to the new location."
(interactive "P")
- (setq org-selected-point (point)
- current-prefix-arg arg)
+ (setq org-goto-selected-point (point)
+ org-goto-exit-command 'return)
(throw 'exit nil))
(defun org-goto-left ()
(if (org-on-heading-p)
(progn
(beginning-of-line 1)
- (setq org-selected-point (point)
- current-prefix-arg (- (match-end 0) (match-beginning 0)))
+ (setq org-goto-selected-point (point)
+ org-goto-exit-command 'left)
(throw 'exit nil))
(error "Not on a heading")))
(interactive)
(if (org-on-heading-p)
(progn
- (outline-end-of-subtree)
- (or (eobp) (forward-char 1))
- (setq org-selected-point (point)
- current-prefix-arg (- (match-end 0) (match-beginning 0)))
+ (setq org-goto-selected-point (point)
+ org-goto-exit-command 'right)
(throw 'exit nil))
(error "Not on a heading")))
(defun org-goto-quit ()
"Finish `org-goto' without cursor motion."
(interactive)
- (setq org-selected-point nil)
+ (setq org-goto-selected-point nil)
+ (setq org-goto-exit-command 'quit)
(throw 'exit nil))
;;; Indirect buffer display of subtrees
"Create indirect buffer and narrow it to current subtree.
With numerical prefix ARG, go up to this level and then take that tree.
If ARG is negative, go up that many levels.
-Normally this command removes the indirect buffer previously made
-with this command. However, when called with a C-u prefix, the last buffer
+If `org-indirect-buffer-display' is not `new-frame', the command removes the
+indirect buffer previously made with this command, to avoid proliferation of
+indirect buffers. However, when you call the command with a `C-u' prefix, or
+when `org-indirect-buffer-display' is `new-frame', the last buffer
is kept so that you can work with several indirect buffers at the same time.
If `org-indirect-buffer-display' is `dedicated-frame', the C-u prefix also
requests that a new frame be made for the new buffer, so that the dedicated
(setq beg (point)
heading (org-get-heading))
(org-end-of-subtree t) (setq end (point)))
- (if (and (not arg)
- (buffer-live-p org-last-indirect-buffer))
+ (if (and (buffer-live-p org-last-indirect-buffer)
+ (not (eq org-indirect-buffer-display 'new-frame))
+ (not arg))
(kill-buffer org-last-indirect-buffer))
(setq ibuf (org-get-indirect-buffer cbuf)
org-last-indirect-buffer ibuf)
"Insert a new heading or item with same depth at point.
If point is in a plain list and FORCE-HEADING is nil, create a new list item.
If point is at the beginning of a headline, insert a sibling before the
-current headline. If point is in the middle of a headline, split the headline
-at that position and make the rest of the headline part of the sibling below
-the current headline."
+current headline. If point is not at the beginning, do not split the line,
+but create the new hedline after the current line."
(interactive "P")
(if (= (buffer-size) 0)
(insert "\n* ")
pos)
(cond
((and (org-on-heading-p) (bolp)
- (save-excursion (backward-char 1) (not (org-invisible-p))))
+ (or (bobp)
+ (save-excursion (backward-char 1) (not (org-invisible-p)))))
+ ;; insert before the current line
(open-line (if blank 2 1)))
- ((and (bolp) (save-excursion
- (backward-char 1) (not (org-invisible-p))))
+ ((and (bolp)
+ (or (bobp)
+ (save-excursion
+ (backward-char 1) (not (org-invisible-p)))))
+ ;; insert right here
nil)
- (t (newline (if blank 2 1))))
+ (t
+; ;; in the middle of the line
+; (org-show-entry)
+; (if (org-get-alist-option org-M-RET-may-split-line 'headline)
+; (if (and
+; (org-on-heading-p)
+; (looking-at ".*?\\([ \t]+\\(:[[:alnum:]_@:]+:\\)\\)[ \r\n]"))
+; ;; protect the tags
+;; (let ((tags (match-string 2)) pos)
+; (delete-region (match-beginning 1) (match-end 1))
+; (setq pos (point-at-bol))
+; (newline (if blank 2 1))
+; (save-excursion
+; (goto-char pos)
+; (end-of-line 1)
+; (insert " " tags)
+; (org-set-tags nil 'align)))
+; (newline (if blank 2 1)))
+; (newline (if blank 2 1))))
+
+
+ ;; in the middle of the line
+ (org-show-entry)
+ (let ((split
+ (org-get-alist-option org-M-RET-may-split-line 'headline))
+ tags pos)
+ (if (org-on-heading-p)
+ (progn
+ (looking-at ".*?\\([ \t]+\\(:[[:alnum:]_@:]+:\\)\\)?[ \t]*$")
+ (setq tags (and (match-end 2) (match-string 2)))
+ (and (match-end 1)
+ (delete-region (match-beginning 1) (match-end 1)))
+ (setq pos (point-at-bol))
+ (or split (end-of-line 1))
+ (delete-horizontal-space)
+ (newline (if blank 2 1))
+ (when tags
+ (save-excursion
+ (goto-char pos)
+ (end-of-line 1)
+ (insert " " tags)
+ (org-set-tags nil 'align))))
+ (or split (end-of-line 1))
+ (newline (if blank 2 1))))))
(insert head) (just-one-space)
(setq pos (point))
(end-of-line 1)
(unless (= (point) pos) (just-one-space) (backward-delete-char 1))
(run-hooks 'org-insert-heading-hook)))))
+(defun org-insert-heading-after-current ()
+ "Insert a new heading with same level as current, after current subtree."
+ (interactive)
+ (org-back-to-heading)
+ (org-insert-heading)
+ (org-move-subtree-down)
+ (end-of-line 1))
(defun org-insert-todo-heading (arg)
"Insert a new heading with the same level and TODO state as current heading.
(looking-at org-todo-line-regexp))
(if (or arg
(not (match-beginning 2))
- (equal (match-string 2) org-done-string))
- (insert (car org-todo-keywords) " ")
+ (member (match-string 2) org-done-keywords))
+ (insert (car org-todo-keywords-1) " ")
(insert (match-string 2) " "))))
+(defun org-insert-subheading (arg)
+ "Insert a new subheading and demote it.
+Works for outline headings and for plain lists alike."
+ (interactive "P")
+ (org-insert-heading arg)
+ (cond
+ ((org-on-heading-p) (org-do-demote))
+ ((org-at-item-p) (org-indent-item 1))))
+
+(defun org-insert-todo-subheading (arg)
+ "Insert a new subheading with TODO keyword or checkbox and demote it.
+Works for outline headings and for plain lists alike."
+ (interactive "P")
+ (org-insert-todo-heading arg)
+ (cond
+ ((org-on-heading-p) (org-do-demote))
+ ((org-at-item-p) (org-indent-item 1))))
+
;;; Promotion and Demotion
(defun org-promote-subtree ()
((eolp) (insert " "))
((equal (char-after) ?\ ) (forward-char 1))))))
-(defun org-get-legal-level (level &optional change)
+(defun org-reduced-level (l)
+ (if org-odd-levels-only (1+ (floor (/ l 2))) l))
+
+(defun org-get-valid-level (level &optional change)
"Rectify a level change under the influence of `org-odd-levels-only'
LEVEL is a current level, CHANGE is by how much the level should be
modified. Even if CHANGE is nil, LEVEL may be returned modified because
((< change 0) (max 1 (1+ (* 2 (/ (+ level (* 2 change)) 2))))))
(max 1 (+ level change))))
+(define-obsolete-function-alias 'org-get-legal-level
+ 'org-get-valid-level "23.1")
+
(defun org-promote ()
"Promote the current heading higher up the tree.
If the region is active in `transient-mark-mode', promote all headings
in the region."
(org-back-to-heading t)
(let* ((level (save-match-data (funcall outline-level)))
- (up-head (make-string (org-get-legal-level level -1) ?*))
- (diff (abs (- level (length up-head)))))
+ (up-head (concat (make-string (org-get-valid-level level -1) ?*) " "))
+ (diff (abs (- level (length up-head) -1))))
(if (= level 1) (error "Cannot promote to level 0. UNDO to recover if necessary"))
(replace-match up-head nil t)
;; Fixup tag positioning
in the region."
(org-back-to-heading t)
(let* ((level (save-match-data (funcall outline-level)))
- (down-head (make-string (org-get-legal-level level 1) ?*))
- (diff (abs (- level (length down-head)))))
+ (down-head (concat (make-string (org-get-valid-level level 1) ?*) " "))
+ (diff (abs (- level (length down-head) -1))))
(replace-match down-head nil t)
;; Fixup tag positioning
(and org-auto-align-tags (org-set-tags nil t))
"^\\S-"
(concat "^ \\{0," (int-to-string (- diff)) "\\}\\S-")))
col)
- (unless (save-excursion (re-search-forward prohibit end t))
- (while (re-search-forward "^[ \t]+" end t)
+ (unless (save-excursion (end-of-line 1)
+ (re-search-forward prohibit end t))
+ (while (and (< (point) end)
+ (re-search-forward "^[ \t]+" end t))
(goto-char (match-end 0))
(setq col (current-column))
(if (< diff 0) (replace-match ""))
(let ((org-odd-levels-only nil) n)
(save-excursion
(goto-char (point-min))
- (while (re-search-forward "^\\*\\*+" nil t)
- (setq n (1- (length (match-string 0))))
+ (while (re-search-forward "^\\*\\*+ " nil t)
+ (setq n (- (length (match-string 0)) 2))
(while (>= (setq n (1- n)) 0)
(org-demote))
(end-of-line 1))))))
(interactive)
(goto-char (point-min))
;; First check if there are no even levels
- (when (re-search-forward "^\\(\\*\\*\\)+[^*]" nil t)
+ (when (re-search-forward "^\\(\\*\\*\\)+ " nil t)
(org-show-context t)
(error "Not all levels are odd in this file. Conversion not possible."))
(when (yes-or-no-p "Are you sure you want to globally change levels to odd-even? ")
(let ((org-odd-levels-only nil) n)
(save-excursion
(goto-char (point-min))
- (while (re-search-forward "^\\*\\*+" nil t)
- (setq n (/ (length (match-string 0)) 2))
+ (while (re-search-forward "^\\*\\*+ " nil t)
+ (setq n (/ (1- (length (match-string 0))) 2))
(while (>= (setq n (1- n)) 0)
(org-promote))
(end-of-line 1))))))
'outline-get-last-sibling))
(ins-point (make-marker))
(cnt (abs arg))
- beg end txt folded)
+ beg beg0 end txt folded ne-beg ne-end ne-ins ins-end)
;; Select the tree
(org-back-to-heading)
- (setq beg (point))
+ (setq beg0 (point))
+ (save-excursion
+ (setq ne-beg (org-back-over-empty-lines))
+ (setq beg (point)))
(save-match-data
(save-excursion (outline-end-of-heading)
(setq folded (org-invisible-p)))
(outline-end-of-subtree))
(outline-next-heading)
+ (setq ne-end (org-back-over-empty-lines))
(setq end (point))
+ (goto-char beg0)
+ (when (and (> arg 0) (org-first-sibling-p) (< ne-end ne-beg))
+ ;; include less whitespace
+ (save-excursion
+ (goto-char beg)
+ (forward-line (- ne-beg ne-end))
+ (setq beg (point))))
;; Find insertion point, with error handling
- (goto-char beg)
(while (> cnt 0)
(or (and (funcall movfunc) (looking-at outline-regexp))
- (progn (goto-char beg)
+ (progn (goto-char beg0)
(error "Cannot move past superior level or buffer limit")))
(setq cnt (1- cnt)))
(if (> arg 0)
;; Moving forward - still need to move over subtree
- (progn (outline-end-of-subtree)
- (outline-next-heading)
- (if (not (or (looking-at (concat "^" outline-regexp))
- (bolp)))
- (newline))))
+ (progn (org-end-of-subtree t t)
+ (save-excursion
+ (org-back-over-empty-lines)
+ (or (bolp) (newline)))))
+ (setq ne-ins (org-back-over-empty-lines))
(move-marker ins-point (point))
(setq txt (buffer-substring beg end))
(delete-region beg end)
+ (outline-flag-region (1- beg) beg nil)
+ (outline-flag-region (1- (point)) (point) nil)
(insert txt)
+ (or (bolp) (insert "\n"))
+ (setq ins-end (point))
(goto-char ins-point)
- (if folded (hide-subtree))
- (move-marker ins-point nil)))
+ (org-skip-whitespace)
+ (when (and (< arg 0)
+ (org-first-sibling-p)
+ (> ne-ins ne-beg))
+ ;; Move whitespace back to beginning
+ (save-excursion
+ (goto-char ins-end)
+ (let ((kill-whole-line t))
+ (kill-line (- ne-ins ne-beg)) (point)))
+ (insert (make-string (- ne-ins ne-beg) ?\n)))
+ (move-marker ins-point nil)
+ (org-compact-display-after-subtree-move)
+ (unless folded
+ (org-show-entry)
+ (show-children)
+ (org-cycle-hide-drawers 'children))))
(defvar org-subtree-clip ""
"Clipboard for cut and paste of subtrees.
"Was the last copied subtree folded?
This is used to fold the tree back after pasting.")
-(defun org-cut-subtree ()
+(defun org-cut-subtree (&optional n)
"Cut the current subtree into the clipboard.
+With prefix arg N, cut this many sequential subtrees.
This is a short-hand for marking the subtree and then cutting it."
- (interactive)
- (org-copy-subtree 'cut))
+ (interactive "p")
+ (org-copy-subtree n 'cut))
-(defun org-copy-subtree (&optional cut)
+(defun org-copy-subtree (&optional n cut)
"Cut the current subtree into the clipboard.
+With prefix arg N, cut this many sequential subtrees.
This is a short-hand for marking the subtree and then copying it.
If CUT is non-nil, actually cut the subtree."
- (interactive)
- (let (beg end folded)
- (org-back-to-heading)
+ (interactive "p")
+ (let (beg end folded (beg0 (point)))
+ (if (interactive-p)
+ (org-back-to-heading nil) ; take what looks like a subtree
+ (org-back-to-heading t)) ; take what is really there
+ (org-back-over-empty-lines)
(setq beg (point))
+ (skip-chars-forward " \t\r\n")
(save-match-data
(save-excursion (outline-end-of-heading)
(setq folded (org-invisible-p)))
- (outline-end-of-subtree))
- (if (equal (char-after) ?\n) (forward-char 1))
+ (condition-case nil
+ (outline-forward-same-level (1- n))
+ (error nil))
+ (org-end-of-subtree t t))
+ (org-back-over-empty-lines)
(setq end (point))
- (goto-char beg)
+ (goto-char beg0)
(when (> end beg)
(setq org-subtree-clip-folded folded)
(if cut (kill-region beg end) (copy-region-as-kill beg end))
(setq org-subtree-clip (current-kill 0))
- (message "%s: Subtree with %d characters"
+ (message "%s: Subtree(s) with %d characters"
(if cut "Cut" "Copied")
(length org-subtree-clip)))))
If optional TREE is given, use this text instead of the kill ring."
(interactive "P")
(unless (org-kill-is-subtree-p tree)
- (error
+ (error "%s"
(substitute-command-keys
"The kill is not a (set of) tree(s) - please use \\[yank] to yank anyway")))
(let* ((txt (or tree (and kill-ring (current-kill 0))))
(^re (concat "^\\(" outline-regexp "\\)"))
(re (concat "\\(" outline-regexp "\\)"))
- (^re_ (concat "\\(" outline-regexp "\\)[ \t]*"))
+ (^re_ (concat "\\(\\*+\\)[ \t]*"))
(old-level (if (string-match ^re txt)
- (- (match-end 0) (match-beginning 0))
+ (- (match-end 0) (match-beginning 0) 1)
-1))
(force-level (cond (level (prefix-numeric-value level))
((string-match
^re_ (buffer-substring (point-at-bol) (point)))
- (- (match-end 0) (match-beginning 0)))
+ (- (match-end 1) (match-beginning 1)))
(t nil)))
(previous-level (save-excursion
(condition-case nil
(progn
(outline-previous-visible-heading 1)
(if (looking-at re)
- (- (match-end 0) (match-beginning 0))
+ (- (match-end 0) (match-beginning 0) 1)
1))
(error 1))))
(next-level (save-excursion
(condition-case nil
(progn
- (outline-next-visible-heading 1)
+ (or (looking-at outline-regexp)
+ (outline-next-visible-heading 1))
(if (looking-at re)
- (- (match-end 0) (match-beginning 0))
+ (- (match-end 0) (match-beginning 0) 1)
1))
(error 1))))
(new-level (or force-level (max previous-level next-level)))
(= old-level new-level))
0
(- new-level old-level)))
- (shift1 shift)
(delta (if (> shift 0) -1 1))
(func (if (> shift 0) 'org-demote 'org-promote))
(org-odd-levels-only nil)
beg end)
- ;; Remove the forces level indicator
+ ;; Remove the forced level indicator
(if force-level
(delete-region (point-at-bol) (point)))
- ;; Make sure we start at the beginning of an empty line
- (if (not (bolp)) (insert "\n"))
- (if (not (looking-at "[ \t]*$"))
- (progn (insert "\n") (backward-char 1)))
;; Paste
+ (beginning-of-line 1)
+ (org-back-over-empty-lines) ;; FIXME: correct fix????
(setq beg (point))
- (if (string-match "[ \t\r\n]+\\'" txt)
- (setq txt (replace-match "\n" t t txt)))
- (insert txt)
+ (insert-before-markers txt) ;; FIXME: correct fix????
+ (unless (string-match "\n\\'" txt) (insert "\n"))
(setq end (point))
- (if (looking-at "[ \t\r\n]+")
- (replace-match "\n"))
(goto-char beg)
+ (skip-chars-forward " \t\n\r")
+ (setq beg (point))
;; Shift if necessary
- (if (= shift 0)
- (message "Pasted at level %d, without shift" new-level)
+ (unless (= shift 0)
(save-restriction
(narrow-to-region beg end)
(while (not (= shift 0))
(org-map-region func (point-min) (point-max))
(setq shift (+ delta shift)))
- (goto-char (point-min))
- (message "Pasted at level %d, with shift by %d levels"
- new-level shift1)))
+ (goto-char (point-min))))
+ (when (interactive-p)
+ (message "Clipboard pasted as level %d subtree" new-level))
(if (and kill-ring
(eq org-subtree-clip (current-kill 0))
org-subtree-clip-folded)
If optional TXT is given, check this string instead of the current kill."
(let* ((kill (or txt (and kill-ring (current-kill 0)) ""))
(start-level (and kill
- (string-match (concat "\\`" outline-regexp) kill)
- (- (match-end 0) (match-beginning 0))))
- (re (concat "^" outline-regexp))
- (start 1))
+ (string-match (concat "\\`\\([ \t\n\r]*?\n\\)?\\("
+ org-outline-regexp "\\)")
+ kill)
+ (- (match-end 2) (match-beginning 2) 1)))
+ (re (concat "^" org-outline-regexp))
+ (start (1+ (match-beginning 2))))
(if (not start-level)
- nil ;; does not even start with a heading
+ (progn
+ nil) ;; does not even start with a heading
(catch 'exit
(while (setq start (string-match re kill (1+ start)))
- (if (< (- (match-end 0) (match-beginning 0)) start-level)
- (throw 'exit nil)))
+ (when (< (- (match-end 0) (match-beginning 0) 1) start-level)
+ (throw 'exit nil)))
t))))
(defun org-narrow-to-subtree ()
"Narrow buffer to the current subtree."
(interactive)
(save-excursion
- (narrow-to-region
- (progn (org-back-to-heading) (point))
- (progn (org-end-of-subtree t) (point)))))
+ (save-match-data
+ (narrow-to-region
+ (progn (org-back-to-heading) (point))
+ (progn (org-end-of-subtree t t) (point))))))
;;; Outline Sorting
(defun org-sort (with-case)
- "Call `org-sort-entries' or `org-table-sort-lines', depending on context."
+ "Call `org-sort-entries-or-items' or `org-table-sort-lines'.
+Optional argument WITH-CASE means sort case-sensitively."
(interactive "P")
(if (org-at-table-p)
(org-call-with-arg 'org-table-sort-lines with-case)
- (org-call-with-arg 'org-sort-entries with-case)))
+ (org-call-with-arg 'org-sort-entries-or-items with-case)))
-(defun org-sort-entries (&optional with-case sorting-type)
+(defvar org-priority-regexp) ; defined later in the file
+
+(defun org-sort-entries-or-items (&optional with-case sorting-type getkey-func property)
"Sort entries on a certain level of an outline tree.
If there is an active region, the entries in the region are sorted.
Else, if the cursor is before the first entry, sort the top-level items.
Sorting can be alphabetically, numerically, and by date/time as given by
the first time stamp in the entry. The command prompts for the sorting
type unless it has been given to the function through the SORTING-TYPE
-argument, which needs to a character, any of (?n ?N ?a ?A ?t ?T).
+argument, which needs to a character, any of (?n ?N ?a ?A ?t ?T ?p ?P ?f ?F).
+If the SORTING-TYPE is ?f or ?F, then GETKEY-FUNC specifies a function to be
+called with point at the beginning of the record. It must return either
+a string or a number that should serve as the sorting key for that record.
Comparing entries ignores case by default. However, with an optional argument
-WITH-CASE, the sorting considers case as well. With two prefix arguments
-`C-u C-u', sorting is case-sensitive and duplicate entries will be removed."
+WITH-CASE, the sorting considers case as well."
(interactive "P")
- (let ((unique (equal with-case '(16)))
- start beg end entries stars re re2 p nentries (nremoved 0)
- last txt what)
+ (let ((case-func (if with-case 'identity 'downcase))
+ start beg end stars re re2
+ txt what tmp plain-list-p)
;; Find beginning and end of region to sort
(cond
((org-region-active-p)
;; we will sort the region
(setq end (region-end)
- what "region")
+ what "region")
(goto-char (region-beginning))
(if (not (org-on-heading-p)) (outline-next-heading))
(setq start (point)))
+ ((org-at-item-p)
+ ;; we will sort this plain list
+ (org-beginning-of-item-list) (setq start (point))
+ (org-end-of-item-list) (setq end (point))
+ (goto-char start)
+ (setq plain-list-p t
+ what "plain list"))
((or (org-on-heading-p)
- (condition-case nil (progn (org-back-to-heading) t) (error nil)))
+ (condition-case nil (progn (org-back-to-heading) t) (error nil)))
;; we will sort the children of the current headline
(org-back-to-heading)
- (setq start (point) end (org-end-of-subtree) what "children")
+ (setq start (point)
+ end (progn (org-end-of-subtree t t)
+ (org-back-over-empty-lines)
+ (point))
+ what "children")
(goto-char start)
(show-subtree)
(outline-next-heading))
(setq start (point) end (point-max) what "top-level")
(goto-char start)
(show-all)))
+
(setq beg (point))
- (if (>= (point) end) (error "Nothing to sort"))
- (looking-at "\\(\\*+\\)")
- (setq stars (match-string 1)
- re (concat "^" (regexp-quote stars) " +")
- re2 (concat "^" (regexp-quote (substring stars 0 -1)) "[^*]")
- txt (buffer-substring beg end))
- (if (not (equal (substring txt -1) "\n")) (setq txt (concat txt "\n")))
- (if (and (not (equal stars "*")) (string-match re2 txt))
- (error "Region to sort contains a level above the first entry"))
- ;; Make a list that can be sorted.
- ;; The car is the string for comparison, the cdr is the subtree
- (message "Sorting entries...")
- (setq entries
- (mapcar
- (lambda (x)
- (string-match "^.*\\(\n.*\\)?" x) ; take two lines
- (cons (match-string 0 x) x))
- (org-split-string txt re)))
+ (if (>= beg end) (error "Nothing to sort"))
+
+ (unless plain-list-p
+ (looking-at "\\(\\*+\\)")
+ (setq stars (match-string 1)
+ re (concat "^" (regexp-quote stars) " +")
+ re2 (concat "^" (regexp-quote (substring stars 0 -1)) "[^*]")
+ txt (buffer-substring beg end))
+ (if (not (equal (substring txt -1) "\n")) (setq txt (concat txt "\n")))
+ (if (and (not (equal stars "*")) (string-match re2 txt))
+ (error "Region to sort contains a level above the first entry")))
+
+ (unless sorting-type
+ (message
+ (if plain-list-p
+ "Sort %s: [a]lpha [n]umeric [t]ime [f]unc A/N/T/F means reversed:"
+ "Sort %s: [a]lpha [n]umeric [t]ime [p]riority p[r]operty [f]unc A/N/T/P/F means reversed:")
+ what)
+ (setq sorting-type (read-char-exclusive))
+
+ (and (= (downcase sorting-type) ?f)
+ (setq getkey-func
+ (completing-read "Sort using function: "
+ obarray 'fboundp t nil nil))
+ (setq getkey-func (intern getkey-func)))
+
+ (and (= (downcase sorting-type) ?r)
+ (setq property
+ (completing-read "Property: "
+ (mapcar 'list (org-buffer-property-keys t))
+ nil t))))
- ;; Sort the list
- (save-excursion
- (goto-char start)
- (setq entries (org-do-sort entries what with-case sorting-type)))
+ (message "Sorting entries...")
- ;; Delete the old stuff
- (goto-char beg)
- (kill-region beg end)
- (setq nentries (length entries))
- ;; Insert the sorted entries, and remove duplicates if this is required
- (while (setq p (pop entries))
- (if (and unique (equal last (setq last (org-trim (cdr p)))))
- (setq nremoved (1+ nremoved)) ; same entry as before, skip it
- (insert stars " " (cdr p))))
- (goto-char start)
- (message "Sorting entries...done (%d entries%s)"
- nentries
- (if unique (format ", %d duplicates removed" nremoved) ""))))
+ (save-restriction
+ (narrow-to-region start end)
+
+ (let ((dcst (downcase sorting-type))
+ (now (current-time)))
+ (sort-subr
+ (/= dcst sorting-type)
+ ;; This function moves to the beginning character of the "record" to
+ ;; be sorted.
+ (if plain-list-p
+ (lambda nil
+ (if (org-at-item-p) t (goto-char (point-max))))
+ (lambda nil
+ (if (re-search-forward re nil t)
+ (goto-char (match-beginning 0))
+ (goto-char (point-max)))))
+ ;; This function moves to the last character of the "record" being
+ ;; sorted.
+ (if plain-list-p
+ 'org-end-of-item
+ (lambda nil
+ (save-match-data
+ (condition-case nil
+ (outline-forward-same-level 1)
+ (error
+ (goto-char (point-max)))))))
+
+ ;; This function returns the value that gets sorted against.
+ (if plain-list-p
+ (lambda nil
+ (when (looking-at "[ \t]*[-+*0-9.)]+[ \t]+")
+ (cond
+ ((= dcst ?n)
+ (string-to-number (buffer-substring (match-end 0)
+ (point-at-eol))))
+ ((= dcst ?a)
+ (buffer-substring (match-end 0) (point-at-eol)))
+ ((= dcst ?t)
+ (if (re-search-forward org-ts-regexp
+ (point-at-eol) t)
+ (org-time-string-to-time (match-string 0))
+ now))
+ ((= dcst ?f)
+ (if getkey-func
+ (progn
+ (setq tmp (funcall getkey-func))
+ (if (stringp tmp) (setq tmp (funcall case-func tmp)))
+ tmp)
+ (error "Invalid key function `%s'" getkey-func)))
+ (t (error "Invalid sorting type `%c'" sorting-type)))))
+ (lambda nil
+ (cond
+ ((= dcst ?n)
+ (if (looking-at outline-regexp)
+ (string-to-number (buffer-substring (match-end 0)
+ (point-at-eol)))
+ nil))
+ ((= dcst ?a)
+ (funcall case-func (buffer-substring (point-at-bol)
+ (point-at-eol))))
+ ((= dcst ?t)
+ (if (re-search-forward org-ts-regexp
+ (save-excursion
+ (forward-line 2)
+ (point)) t)
+ (org-time-string-to-time (match-string 0))
+ now))
+ ((= dcst ?p)
+ (if (re-search-forward org-priority-regexp (point-at-eol) t)
+ (string-to-char (match-string 2))
+ org-default-priority))
+ ((= dcst ?r)
+ (or (org-entry-get nil property) ""))
+ ((= dcst ?f)
+ (if getkey-func
+ (progn
+ (setq tmp (funcall getkey-func))
+ (if (stringp tmp) (setq tmp (funcall case-func tmp)))
+ tmp)
+ (error "Invalid key function `%s'" getkey-func)))
+ (t (error "Invalid sorting type `%c'" sorting-type)))))
+ nil
+ (cond
+ ((= dcst ?a) 'string<)
+ ((= dcst ?t) 'time-less-p)
+ (t nil)))))
+ (message "Sorting entries...done")))
(defun org-do-sort (table what &optional with-case sorting-type)
"Sort TABLE of WHAT according to SORTING-TYPE.
If WITH-CASE is non-nil, the sorting will be case-sensitive."
(unless sorting-type
(message
- "Sort %s: [a]lphabetically [n]umerically [t]ime. A/N/T means reversed:"
+ "Sort %s: [a]lphabetic. [n]umeric. [t]ime. A/N/T means reversed:"
what)
(setq sorting-type (read-char-exclusive)))
(let ((dcst (downcase sorting-type))
(setq extractfun 'string-to-number
comparefun (if (= dcst sorting-type) '< '>)))
((= dcst ?a)
- (setq extractfun (if with-case 'identity 'downcase)
+ (setq extractfun (if with-case (lambda(x) (org-sort-remove-invisible x))
+ (lambda(x) (downcase (org-sort-remove-invisible x))))
comparefun (if (= dcst sorting-type)
'string<
(lambda (a b) (and (not (string< a b))
(cond
((eq llt t) "\\([ \t]*\\([-+]\\|\\([0-9]+[.)]\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
((= llt ?.) "\\([ \t]*\\([-+]\\|\\([0-9]+\\.\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
- ((= llt ?\)) "\\([ \t]*\\([-+]\\|\\([0-9]+)\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
+ ((= llt ?\)) "\\([ \t]*\\([-+]\\|\\([0-9]+))\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
(t (error "Invalid value of `org-plain-list-ordered-item-terminator'")))))))
-
(defun org-in-item-p ()
"It the cursor inside a plain list item.
Does not have to be the first line."
(open-line (if blank 2 1)))
((<= (point) eow)
(beginning-of-line 1))
- (t (newline (if blank 2 1))))
+ (t
+ (unless (org-get-alist-option org-M-RET-may-split-line 'item)
+ (end-of-line 1)
+ (delete-horizontal-space))
+ (newline (if blank 2 1))))
(insert bul (if checkbox "[ ]" ""))
(just-one-space)
(setq pos (point))
(save-excursion
(goto-char (match-end 0))
(skip-chars-forward " \t")
- (looking-at "\\[[ X]\\]"))))
+ (looking-at "\\[[- X]\\]"))))
(defun org-toggle-checkbox (&optional arg)
"Toggle the checkbox in the current line."
((org-on-heading-p)
(setq beg (point) end (save-excursion (outline-next-heading) (point))))
((org-at-item-checkbox-p)
- (save-excursion
- (replace-match (if (equal (match-string 0) "[ ]") "[X]" "[ ]") t t))
+ (let ((pos (point)))
+ (replace-match
+ (cond (arg "[-]")
+ ((member (match-string 0) '("[ ]" "[-]")) "[X]")
+ (t "[ ]"))
+ t t)
+ (goto-char pos))
(throw 'exit t))
(t (error "Not at a checkbox or heading, and no active region")))
(save-excursion
(org-update-checkbox-count)))
(defun org-update-checkbox-count (&optional all)
- "Update the checkbox statistics in the current section.
+ "Update the checkbox statistics in the current section.
This will find all statistic cookies like [57%] and [6/12] and update them
with the current numbers. With optional prefix argument ALL, do this for
the whole buffer."
- (interactive "P")
- (save-excursion
- (let* ((buffer-invisibility-spec nil) ; Emacs 21 compatibility
- (beg (progn (outline-back-to-heading) (point)))
- (end (move-marker (make-marker)
- (progn (outline-next-heading) (point))))
- (re "\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)")
- (re-box "^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(\\[[ X]\\]\\)")
- b1 e1 f1 c-on c-off lim (cstat 0))
- (when all
- (goto-char (point-min))
- (outline-next-heading)
- (setq beg (point) end (point-max)))
- (goto-char beg)
- (while (re-search-forward re end t)
- (setq cstat (1+ cstat)
- b1 (match-beginning 0)
- e1 (match-end 0)
- f1 (match-beginning 1)
- lim (cond
- ((org-on-heading-p) (outline-next-heading) (point))
- ((org-at-item-p) (org-end-of-item) (point))
- (t nil))
- c-on 0 c-off 0)
- (goto-char e1)
- (when lim
- (while (re-search-forward re-box lim t)
- (if (equal (match-string 2) "[ ]")
- (setq c-off (1+ c-off))
- (setq c-on (1+ c-on))))
- (delete-region b1 e1)
- (goto-char b1)
- (insert (if f1
- (format "[%d%%]" (/ (* 100 c-on) (max 1 (+ c-on c-off))))
- (format "[%d/%d]" c-on (+ c-on c-off))))))
- (when (interactive-p)
- (message "Checkbox satistics updated %s (%d places)"
- (if all "in entire file" "in current outline entry") cstat)))))
+ (interactive "P")
+ (save-excursion
+ (let* ((buffer-invisibility-spec (org-inhibit-invisibility)) ; Emacs 21
+ (beg (condition-case nil
+ (progn (outline-back-to-heading) (point))
+ (error (point-min))))
+ (end (move-marker (make-marker)
+ (progn (outline-next-heading) (point))))
+ (re "\\(\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)\\)")
+ (re-box "^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(\\[[- X]\\]\\)")
+ (re-find (concat re "\\|" re-box))
+ beg-cookie end-cookie is-percent c-on c-off lim
+ eline curr-ind next-ind continue-from startsearch
+ (cstat 0)
+ )
+ (when all
+ (goto-char (point-min))
+ (outline-next-heading)
+ (setq beg (point) end (point-max)))
+ (goto-char end)
+ ;; find each statistic cookie
+ (while (re-search-backward re-find beg t)
+ (setq beg-cookie (match-beginning 1)
+ end-cookie (match-end 1)
+ cstat (+ cstat (if end-cookie 1 0))
+ startsearch (point-at-eol)
+ continue-from (point-at-bol)
+ is-percent (match-beginning 2)
+ lim (cond
+ ((org-on-heading-p) (outline-next-heading) (point))
+ ((org-at-item-p) (org-end-of-item) (point))
+ (t nil))
+ c-on 0
+ c-off 0)
+ (when lim
+ ;; find first checkbox for this cookie and gather
+ ;; statistics from all that are at this indentation level
+ (goto-char startsearch)
+ (if (re-search-forward re-box lim t)
+ (progn
+ (org-beginning-of-item)
+ (setq curr-ind (org-get-indentation))
+ (setq next-ind curr-ind)
+ (while (= curr-ind next-ind)
+ (save-excursion (end-of-line) (setq eline (point)))
+ (if (re-search-forward re-box eline t)
+ (if (member (match-string 2) '("[ ]" "[-]"))
+ (setq c-off (1+ c-off))
+ (setq c-on (1+ c-on))
+ )
+ )
+ (org-end-of-item)
+ (setq next-ind (org-get-indentation))
+ )))
+ (goto-char continue-from)
+ ;; update cookie
+ (when end-cookie
+ (delete-region beg-cookie end-cookie)
+ (goto-char beg-cookie)
+ (insert
+ (if is-percent
+ (format "[%d%%]" (/ (* 100 c-on) (max 1 (+ c-on c-off))))
+ (format "[%d/%d]" c-on (+ c-on c-off)))))
+ ;; update items checkbox if it has one
+ (when (org-at-item-p)
+ (org-beginning-of-item)
+ (when (and (> (+ c-on c-off) 0)
+ (re-search-forward re-box (point-at-eol) t))
+ (setq beg-cookie (match-beginning 2)
+ end-cookie (match-end 2))
+ (delete-region beg-cookie end-cookie)
+ (goto-char beg-cookie)
+ (cond ((= c-off 0) (insert "[X]"))
+ ((= c-on 0) (insert "[ ]"))
+ (t (insert "[-]")))
+ )))
+ (goto-char continue-from))
+ (when (interactive-p)
+ (message "Checkbox satistics updated %s (%d places)"
+ (if all "in entire file" "in current outline entry") cstat)))))
(defun org-get-checkbox-statistics-face ()
"Select the face for checkbox statistics.
(concat (make-string i1 ?\ ) l)
l)))
+(defcustom org-empty-line-terminates-plain-lists nil
+ "Non-nil means, an empty line ends all plain list levels.
+When nil, empty lines are part of the preceeding item."
+ :group 'org-plain-lists
+ :type 'boolean)
+
(defun org-beginning-of-item ()
"Go to the beginning of the current hand-formatted item.
If the cursor is not in an item, throw an error."
(interactive)
(let ((pos (point))
- (limit (save-excursion (org-back-to-heading)
- (beginning-of-line 2) (point)))
+ (limit (save-excursion
+ (condition-case nil
+ (progn
+ (org-back-to-heading)
+ (beginning-of-line 2) (point))
+ (error (point-min)))))
+ (ind-empty (if org-empty-line-terminates-plain-lists 0 10000))
ind ind1)
(if (org-at-item-p)
(beginning-of-line 1)
(if (catch 'exit
(while t
(beginning-of-line 0)
- (if (< (point) limit) (throw 'exit nil))
- (unless (looking-at "[ \t]*$")
+ (if (or (bobp) (< (point) limit)) (throw 'exit nil))
+
+ (if (looking-at "[ \t]*$")
+ (setq ind1 ind-empty)
(skip-chars-forward " \t")
- (setq ind1 (current-column))
- (if (< ind1 ind)
- (throw 'exit (org-at-item-p))))))
+ (setq ind1 (current-column)))
+ (if (< ind1 ind)
+ (progn (beginning-of-line 1) (throw 'exit (org-at-item-p))))))
nil
(goto-char pos)
(error "Not in an item")))))
"Go to the end of the current hand-formatted item.
If the cursor is not in an item, throw an error."
(interactive)
- (let ((pos (point))
- (limit (save-excursion (outline-next-heading) (point)))
- (ind (save-excursion
- (org-beginning-of-item)
- (skip-chars-forward " \t")
- (current-column)))
- ind1)
- (if (catch 'exit
- (while t
- (beginning-of-line 2)
- (if (>= (point) limit) (throw 'exit t))
- (unless (looking-at "[ \t]*$")
- (skip-chars-forward " \t")
- (setq ind1 (current-column))
- (if (<= ind1 ind) (throw 'exit t)))))
- (beginning-of-line 1)
+ (let* ((pos (point))
+ ind1
+ (ind-empty (if org-empty-line-terminates-plain-lists 0 10000))
+ (limit (save-excursion (outline-next-heading) (point)))
+ (ind (save-excursion
+ (org-beginning-of-item)
+ (skip-chars-forward " \t")
+ (current-column)))
+ (end (catch 'exit
+ (while t
+ (beginning-of-line 2)
+ (if (eobp) (throw 'exit (point)))
+ (if (>= (point) limit) (throw 'exit (point-at-bol)))
+ (if (looking-at "[ \t]*$")
+ (setq ind1 ind-empty)
+ (skip-chars-forward " \t")
+ (setq ind1 (current-column)))
+ (if (<= ind1 ind)
+ (throw 'exit (point-at-bol)))))))
+ (if end
+ (goto-char end)
(goto-char pos)
(error "Not in an item"))))
(defun org-previous-item ()
"Move to the beginning of the previous item in the current plain list.
-Error if not at a plain list, or if this is the last item in the list."
+Error if not at a plain list, or if this is the first item in the list."
(interactive)
- (let (beg ind (pos (point)))
+ (let (beg ind ind1 (pos (point)))
(org-beginning-of-item)
(setq beg (point))
(setq ind (org-get-indentation))
(beginning-of-line 0)
(if (looking-at "[ \t]*$")
nil
- (if (<= (org-get-indentation) ind)
+ (if (<= (setq ind1 (org-get-indentation)) ind)
(throw 'exit t)))))
(condition-case nil
- (org-beginning-of-item)
+ (if (or (not (org-at-item-p))
+ (< ind1 (1- ind)))
+ (error "")
+ (org-beginning-of-item))
(error (goto-char pos)
(error "On first item")))))
+(defun org-first-list-item-p ()
+ "Is this heading the item in a plain list?"
+ (unless (org-at-item-p)
+ (error "Not at a plain list item"))
+ (org-beginning-of-item)
+ (= (point) (save-excursion (org-beginning-of-item-list))))
+
(defun org-move-item-down ()
"Move the plain list item at point down, i.e. swap with following item.
Subitems (items with larger indentation) are considered part of the item,
so this really moves item trees."
(interactive)
- (let (beg end ind ind1 (pos (point)) txt)
+ (let (beg beg0 end end0 ind ind1 (pos (point)) txt ne-end ne-beg)
(org-beginning-of-item)
- (setq beg (point))
+ (setq beg0 (point))
+ (save-excursion
+ (setq ne-beg (org-back-over-empty-lines))
+ (setq beg (point)))
+ (goto-char beg0)
(setq ind (org-get-indentation))
(org-end-of-item)
- (setq end (point))
+ (setq end0 (point))
(setq ind1 (org-get-indentation))
+ (setq ne-end (org-back-over-empty-lines))
+ (setq end (point))
+ (goto-char beg0)
+ (when (and (org-first-list-item-p) (< ne-end ne-beg))
+ ;; include less whitespace
+ (save-excursion
+ (goto-char beg)
+ (forward-line (- ne-beg ne-end))
+ (setq beg (point))))
+ (goto-char end0)
(if (and (org-at-item-p) (= ind ind1))
(progn
(org-end-of-item)
+ (org-back-over-empty-lines)
(setq txt (buffer-substring beg end))
(save-excursion
(delete-region beg end))
(setq pos (point))
(insert txt)
- (goto-char pos)
+ (goto-char pos) (org-skip-whitespace)
(org-maybe-renumber-ordered-list))
(goto-char pos)
(error "Cannot move this item further down"))))
Subitems (items with larger indentation) are considered part of the item,
so this really moves item trees."
(interactive "p")
- (let (beg end ind ind1 (pos (point)) txt)
+ (let (beg beg0 end ind ind1 (pos (point)) txt
+ ne-beg ne-ins ins-end)
(org-beginning-of-item)
- (setq beg (point))
+ (setq beg0 (point))
(setq ind (org-get-indentation))
+ (save-excursion
+ (setq ne-beg (org-back-over-empty-lines))
+ (setq beg (point)))
+ (goto-char beg0)
(org-end-of-item)
(setq end (point))
- (goto-char beg)
+ (goto-char beg0)
(catch 'exit
(while t
(beginning-of-line 0)
(if (looking-at "[ \t]*$")
- nil
+ (if org-empty-line-terminates-plain-lists
+ (progn
+ (goto-char pos)
+ (error "Cannot move this item further up"))
+ nil)
(if (<= (setq ind1 (org-get-indentation)) ind)
(throw 'exit t)))))
(condition-case nil
(setq ind1 (org-get-indentation))
(if (and (org-at-item-p) (= ind ind1))
(progn
+ (setq ne-ins (org-back-over-empty-lines))
(setq txt (buffer-substring beg end))
(save-excursion
(delete-region beg end))
(setq pos (point))
(insert txt)
- (goto-char pos)
+ (setq ins-end (point))
+ (goto-char pos) (org-skip-whitespace)
+
+ (when (and (org-first-list-item-p) (> ne-ins ne-beg))
+ ;; Move whitespace back to beginning
+ (save-excursion
+ (goto-char ins-end)
+ (let ((kill-whole-line t))
+ (kill-line (- ne-ins ne-beg)) (point)))
+ (insert (make-string (- ne-ins ne-beg) ?\n)))
+
(org-maybe-renumber-ordered-list))
(goto-char pos)
(error "Cannot move this item further up"))))
"Renumber the ordered list at point if setup allows it.
This tests the user option `org-auto-renumber-ordered-lists' before
doing the renumbering."
- (and org-auto-renumber-ordered-lists
- (org-at-item-p)
- (match-beginning 3)
- (org-renumber-ordered-list 1)))
+ (interactive)
+ (when (and org-auto-renumber-ordered-lists
+ (org-at-item-p))
+ (if (match-beginning 3)
+ (org-renumber-ordered-list 1)
+ (org-fix-bullet-type))))
+
+(defun org-maybe-renumber-ordered-list-safe ()
+ (condition-case nil
+ (save-excursion
+ (org-maybe-renumber-ordered-list))
+ (error nil)))
+
+(defun org-cycle-list-bullet (&optional which)
+ "Cycle through the different itemize/enumerate bullets.
+This cycle the entire list level through the sequence:
+
+ `-' -> `+' -> `*' -> `1.' -> `1)'
+
+If WHICH is a string, use that as the new bullet. If WHICH is an integer,
+0 meand `-', 1 means `+' etc."
+ (interactive "P")
+ (org-preserve-lc
+ (org-beginning-of-item-list)
+ (org-at-item-p)
+ (beginning-of-line 1)
+ (let ((current (match-string 0))
+ (prevp (eq which 'previous))
+ new)
+ (setq new (cond
+ ((and (numberp which)
+ (nth (1- which) '("-" "+" "*" "1." "1)"))))
+ ((string-match "-" current) (if prevp "1)" "+"))
+ ((string-match "\\+" current)
+ (if prevp "-" (if (looking-at "\\S-") "1." "*")))
+ ((string-match "\\*" current) (if prevp "+" "1."))
+ ((string-match "\\." current) (if prevp "*" "1)"))
+ ((string-match ")" current) (if prevp "1." "-"))
+ (t (error "This should not happen"))))
+ (and (looking-at "\\([ \t]*\\)\\S-+") (replace-match (concat "\\1" new)))
+ (org-fix-bullet-type)
+ (org-maybe-renumber-ordered-list))))
(defun org-get-string-indentation (s)
"What indentation has S due to SPACE and TAB at the beginning of the string?"
(ind (org-get-string-indentation
(buffer-substring (point-at-bol) (match-beginning 3))))
;; (term (substring (match-string 3) -1))
- ind1 (n (1- arg)))
+ ind1 (n (1- arg))
+ fmt)
;; find where this list begins
+ (org-beginning-of-item-list)
+ (looking-at "[ \t]*[0-9]+\\([.)]\\)")
+ (setq fmt (concat "%d" (match-string 1)))
+ (beginning-of-line 0)
+ ;; walk forward and replace these numbers
(catch 'exit
(while t
(catch 'next
- (beginning-of-line 0)
- (if (looking-at "[ \t]*$") (throw 'next t))
+ (beginning-of-line 2)
+ (if (eobp) (throw 'exit nil))
+ (if (looking-at "[ \t]*$") (throw 'next nil))
(skip-chars-forward " \t") (setq ind1 (current-column))
- (if (or (< ind1 ind)
- (and (= ind1 ind)
- (not (org-at-item-p))))
- (throw 'exit t)))))
- ;; Walk forward and replace these numbers
+ (if (> ind1 ind) (throw 'next t))
+ (if (< ind1 ind) (throw 'exit t))
+ (if (not (org-at-item-p)) (throw 'exit nil))
+ (delete-region (match-beginning 2) (match-end 2))
+ (goto-char (match-beginning 2))
+ (insert (format fmt (setq n (1+ n)))))))
+ (goto-line line)
+ (move-to-column col)))
+
+(defun org-fix-bullet-type ()
+ "Make sure all items in this list have the same bullet as the firsst item."
+ (interactive)
+ (unless (org-at-item-p) (error "This is not a list"))
+ (let ((line (org-current-line))
+ (col (current-column))
+ (ind (current-indentation))
+ ind1 bullet)
+ ;; find where this list begins
+ (org-beginning-of-item-list)
+ (beginning-of-line 1)
+ ;; find out what the bullet type is
+ (looking-at "[ \t]*\\(\\S-+\\)")
+ (setq bullet (match-string 1))
+ ;; walk forward and replace these numbers
+ (beginning-of-line 0)
(catch 'exit
(while t
(catch 'next
(if (> ind1 ind) (throw 'next t))
(if (< ind1 ind) (throw 'exit t))
(if (not (org-at-item-p)) (throw 'exit nil))
- (if (not (match-beginning 3))
- (error "unordered bullet in ordered list. Press \\[undo] to recover"))
- (delete-region (match-beginning 3) (1- (match-end 3)))
- (goto-char (match-beginning 3))
- (insert (format "%d" (setq n (1+ n)))))))
+ (skip-chars-forward " \t")
+ (looking-at "\\S-+")
+ (replace-match bullet))))
(goto-line line)
- (move-to-column col)))
+ (move-to-column col)
+ (if (string-match "[0-9]" bullet)
+ (org-renumber-ordered-list 1))))
+
+(defun org-beginning-of-item-list ()
+ "Go to the beginning of the current item list.
+I.e. to the first item in this list."
+ (interactive)
+ (org-beginning-of-item)
+ (let ((pos (point-at-bol))
+ (ind (org-get-indentation))
+ ind1)
+ ;; find where this list begins
+ (catch 'exit
+ (while t
+ (catch 'next
+ (beginning-of-line 0)
+ (if (looking-at "[ \t]*$")
+ (throw (if (bobp) 'exit 'next) t))
+ (skip-chars-forward " \t") (setq ind1 (current-column))
+ (if (or (< ind1 ind)
+ (and (= ind1 ind)
+ (not (org-at-item-p)))
+ (bobp))
+ (throw 'exit t)
+ (when (org-at-item-p) (setq pos (point-at-bol)))))))
+ (goto-char pos)))
+
+
+(defun org-end-of-item-list ()
+ "Go to the end of the current item list.
+I.e. to the text after the last item."
+ (interactive)
+ (org-beginning-of-item)
+ (let ((pos (point-at-bol))
+ (ind (org-get-indentation))
+ ind1)
+ ;; find where this list begins
+ (catch 'exit
+ (while t
+ (catch 'next
+ (beginning-of-line 2)
+ (if (looking-at "[ \t]*$")
+ (throw (if (eobp) 'exit 'next) t))
+ (skip-chars-forward " \t") (setq ind1 (current-column))
+ (if (or (< ind1 ind)
+ (and (= ind1 ind)
+ (not (org-at-item-p)))
+ (eobp))
+ (progn
+ (setq pos (point-at-bol))
+ (throw 'exit t))))))
+ (goto-char pos)))
+
(defvar org-last-indent-begin-marker (make-marker))
(defvar org-last-indent-end-marker (make-marker))
(unless (org-at-item-p)
(error "Not on an item"))
(save-excursion
- (let (beg end ind ind1)
+ (let (beg end ind ind1 tmp delta ind-down ind-up)
(if (memq last-command '(org-shiftmetaright org-shiftmetaleft))
(setq beg org-last-indent-begin-marker
end org-last-indent-end-marker)
(org-end-of-item)
(setq end (move-marker org-last-indent-end-marker (point))))
(goto-char beg)
- (skip-chars-forward " \t") (setq ind (current-column))
- (if (< (+ arg ind) 0) (error "Cannot outdent beyond margin"))
+ (setq tmp (org-item-indent-positions)
+ ind (car tmp)
+ ind-down (nth 2 tmp)
+ ind-up (nth 1 tmp)
+ delta (if (> arg 0)
+ (if ind-down (- ind-down ind) 2)
+ (if ind-up (- ind-up ind) -2)))
+ (if (< (+ delta ind) 0) (error "Cannot outdent beyond margin"))
(while (< (point) end)
(beginning-of-line 1)
(skip-chars-forward " \t") (setq ind1 (current-column))
(delete-region (point-at-bol) (point))
- (indent-to-column (+ ind1 arg))
- (beginning-of-line 2)))))
+ (or (eolp) (indent-to-column (+ ind1 delta)))
+ (beginning-of-line 2))))
+ (org-fix-bullet-type)
+ (org-maybe-renumber-ordered-list-safe)
+ (save-excursion
+ (beginning-of-line 0)
+ (condition-case nil (org-beginning-of-item) (error nil))
+ (org-maybe-renumber-ordered-list-safe)))
+
+(defun org-item-indent-positions ()
+ "Return indentation for plain list items.
+This returns a list with three values: The current indentation, the
+parent indentation and the indentation a child should habe.
+Assumes cursor in item line."
+ (let* ((bolpos (point-at-bol))
+ (ind (org-get-indentation))
+ ind-down ind-up pos)
+ (save-excursion
+ (org-beginning-of-item-list)
+ (skip-chars-backward "\n\r \t")
+ (when (org-in-item-p)
+ (org-beginning-of-item)
+ (setq ind-up (org-get-indentation))))
+ (setq pos (point))
+ (save-excursion
+ (cond
+ ((and (condition-case nil (progn (org-previous-item) t)
+ (error nil))
+ (or (forward-char 1) t)
+ (re-search-forward "^\\([ \t]*\\([-+]\\|\\([0-9]+[.)]\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)" bolpos t))
+ (setq ind-down (org-get-indentation)))
+ ((and (goto-char pos)
+ (org-at-item-p))
+ (goto-char (match-end 0))
+ (skip-chars-forward " \t")
+ (setq ind-down (current-column)))))
+ (list ind ind-up ind-down)))
+
+;;; The orgstruct minor mode
-;;;; Archiving
+;; Define a minor mode which can be used in other modes in order to
+;; integrate the org-mode structure editing commands.
+
+;; This is really a hack, because the org-mode structure commands use
+;; keys which normally belong to the major mode. Here is how it
+;; works: The minor mode defines all the keys necessary to operate the
+;; structure commands, but wraps the commands into a function which
+;; tests if the cursor is currently at a headline or a plain list
+;; item. If that is the case, the structure command is used,
+;; temporarily setting many Org-mode variables like regular
+;; expressions for filling etc. However, when any of those keys is
+;; used at a different location, function uses `key-binding' to look
+;; up if the key has an associated command in another currently active
+;; keymap (minor modes, major mode, global), and executes that
+;; command. There might be problems if any of the keys is otherwise
+;; used as a prefix key.
-(defalias 'org-advertized-archive-subtree 'org-archive-subtree)
+;; Another challenge is that the key binding for TAB can be tab or \C-i,
+;; likewise the binding for RET can be return or \C-m. Orgtbl-mode
+;; addresses this by checking explicitly for both bindings.
-(defun org-archive-subtree (&optional find-done)
- "Move the current subtree to the archive.
-The archive can be a certain top-level heading in the current file, or in
-a different file. The tree will be moved to that location, the subtree
-heading be marked DONE, and the current time will be added.
+(defvar orgstruct-mode-map (make-sparse-keymap)
+ "Keymap for the minor `orgstruct-mode'.")
-When called with prefix argument FIND-DONE, find whole trees without any
-open TODO items and archive them (after getting confirmation from the user).
-If the cursor is not at a headline when this comand is called, try all level
-1 trees. If the cursor is on a headline, only try the direct children of
-this heading. "
- (interactive "P")
- (if find-done
- (org-archive-all-done)
- ;; Save all relevant TODO keyword-relatex variables
+(defvar org-local-vars nil
+ "List of local variables, for use by `orgstruct-mode'")
- (let ((tr-org-todo-line-regexp org-todo-line-regexp) ; keep despite compiler
- (tr-org-todo-keywords org-todo-keywords)
- (tr-org-todo-interpretation org-todo-interpretation)
- (tr-org-done-string org-done-string)
- (tr-org-todo-regexp org-todo-regexp)
- (tr-org-todo-line-regexp org-todo-line-regexp)
- (tr-org-odd-levels-only org-odd-levels-only)
- (this-buffer (current-buffer))
- (org-archive-location org-archive-location)
- (re "^#\\+ARCHIVE:[ \t]+\\(\\S-.*\\S-\\)[ \t]*$")
- file heading buffer level newfile-p)
+;;;###autoload
+(define-minor-mode orgstruct-mode
+ "Toggle the minor more `orgstruct-mode'.
+This mode is for using Org-mode structure commands in other modes.
+The following key behave as if Org-mode was active, if the cursor
+is on a headline, or on a plain list item (both in the definition
+of Org-mode).
+
+M-up Move entry/item up
+M-down Move entry/item down
+M-left Promote
+M-right Demote
+M-S-up Move entry/item up
+M-S-down Move entry/item down
+M-S-left Promote subtree
+M-S-right Demote subtree
+M-q Fill paragraph and items like in Org-mode
+C-c ^ Sort entries
+C-c - Cycle list bullet
+TAB Cycle item visibility
+M-RET Insert new heading/item
+S-M-RET Insert new TODO heading / Chekbox item
+C-c C-c Set tags / toggle checkbox"
+ nil " OrgStruct" nil
+ (and (orgstruct-setup) (defun orgstruct-setup () nil)))
- ;; Try to find a local archive location
- (save-excursion
- (if (or (re-search-backward re nil t) (re-search-forward re nil t))
- (setq org-archive-location (match-string 1))))
+;;;###autoload
+(defun turn-on-orgstruct ()
+ "Unconditionally turn on `orgstruct-mode'."
+ (orgstruct-mode 1))
- (if (string-match "\\(.*\\)::\\(.*\\)" org-archive-location)
- (progn
- (setq file (format (match-string 1 org-archive-location)
+;;;###autoload
+(defun turn-on-orgstruct++ ()
+ "Unconditionally turn on `orgstruct-mode', and force org-mode indentations.
+In addition to setting orgstruct-mode, this also exports all indentation and
+autofilling variables from org-mode into the buffer. Note that turning
+off orgstruct-mode will *not* remove these additional settings."
+ (orgstruct-mode 1)
+ (let (var val)
+ (mapc
+ (lambda (x)
+ (when (string-match
+ "^\\(paragraph-\\|auto-fill\\|fill-paragraph\\|adaptive-fill\\|indent-\\)"
+ (symbol-name (car x)))
+ (setq var (car x) val (nth 1 x))
+ (org-set-local var (if (eq (car-safe val) 'quote) (nth 1 val) val))))
+ org-local-vars)))
+
+(defun orgstruct-error ()
+ "Error when there is no default binding for a structure key."
+ (interactive)
+ (error "This key has no function outside structure elements"))
+
+(defun orgstruct-setup ()
+ "Setup orgstruct keymaps."
+ (let ((nfunc 0)
+ (bindings
+ (list
+ '([(meta up)] org-metaup)
+ '([(meta down)] org-metadown)
+ '([(meta left)] org-metaleft)
+ '([(meta right)] org-metaright)
+ '([(meta shift up)] org-shiftmetaup)
+ '([(meta shift down)] org-shiftmetadown)
+ '([(meta shift left)] org-shiftmetaleft)
+ '([(meta shift right)] org-shiftmetaright)
+ '([(shift up)] org-shiftup)
+ '([(shift down)] org-shiftdown)
+ '("\C-c\C-c" org-ctrl-c-ctrl-c)
+ '("\M-q" fill-paragraph)
+ '("\C-c^" org-sort)
+ '("\C-c-" org-cycle-list-bullet)))
+ elt key fun cmd)
+ (while (setq elt (pop bindings))
+ (setq nfunc (1+ nfunc))
+ (setq key (org-key (car elt))
+ fun (nth 1 elt)
+ cmd (orgstruct-make-binding fun nfunc key))
+ (org-defkey orgstruct-mode-map key cmd))
+
+ ;; Special treatment needed for TAB and RET
+ (org-defkey orgstruct-mode-map [(tab)]
+ (orgstruct-make-binding 'org-cycle 102 [(tab)] "\C-i"))
+ (org-defkey orgstruct-mode-map "\C-i"
+ (orgstruct-make-binding 'org-cycle 103 "\C-i" [(tab)]))
+
+ (org-defkey orgstruct-mode-map "\M-\C-m"
+ (orgstruct-make-binding 'org-insert-heading 105
+ "\M-\C-m" [(meta return)]))
+ (org-defkey orgstruct-mode-map [(meta return)]
+ (orgstruct-make-binding 'org-insert-heading 106
+ [(meta return)] "\M-\C-m"))
+
+ (org-defkey orgstruct-mode-map [(shift meta return)]
+ (orgstruct-make-binding 'org-insert-todo-heading 107
+ [(meta return)] "\M-\C-m"))
+
+ (unless org-local-vars
+ (setq org-local-vars (org-get-local-variables)))
+
+ t))
+
+(defun orgstruct-make-binding (fun n &rest keys)
+ "Create a function for binding in the structure minor mode.
+FUN is the command to call inside a table. N is used to create a unique
+command name. KEYS are keys that should be checked in for a command
+to execute outside of tables."
+ (eval
+ (list 'defun
+ (intern (concat "orgstruct-hijacker-command-" (int-to-string n)))
+ '(arg)
+ (concat "In Structure, run `" (symbol-name fun) "'.\n"
+ "Outside of structure, run the binding of `"
+ (mapconcat (lambda (x) (format "%s" x)) keys "' or `")
+ "'.")
+ '(interactive "p")
+ (list 'if
+ '(org-context-p 'headline 'item)
+ (list 'org-run-like-in-org-mode (list 'quote fun))
+ (list 'let '(orgstruct-mode)
+ (list 'call-interactively
+ (append '(or)
+ (mapcar (lambda (k)
+ (list 'key-binding k))
+ keys)
+ '('orgstruct-error))))))))
+
+(defun org-context-p (&rest contexts)
+ "Check if local context is and of CONTEXTS.
+Possible values in the list of contexts are `table', `headline', and `item'."
+ (let ((pos (point)))
+ (goto-char (point-at-bol))
+ (prog1 (or (and (memq 'table contexts)
+ (looking-at "[ \t]*|"))
+ (and (memq 'headline contexts)
+ (looking-at "\\*+"))
+ (and (memq 'item contexts)
+ (looking-at "[ \t]*\\([-+*] \\|[0-9]+[.)] \\)")))
+ (goto-char pos))))
+
+(defun org-get-local-variables ()
+ "Return a list of all local variables in an org-mode buffer."
+ (let (varlist)
+ (with-current-buffer (get-buffer-create "*Org tmp*")
+ (erase-buffer)
+ (org-mode)
+ (setq varlist (buffer-local-variables)))
+ (kill-buffer "*Org tmp*")
+ (delq nil
+ (mapcar
+ (lambda (x)
+ (setq x
+ (if (symbolp x)
+ (list x)
+ (list (car x) (list 'quote (cdr x)))))
+ (if (string-match
+ "^\\(org-\\|orgtbl-\\|outline-\\|comment-\\|paragraph-\\|auto-fill\\|fill-paragraph\\|adaptive-fill\\|indent-\\)"
+ (symbol-name (car x)))
+ x nil))
+ varlist))))
+
+;;;###autoload
+(defun org-run-like-in-org-mode (cmd)
+ (unless org-local-vars
+ (setq org-local-vars (org-get-local-variables)))
+ (eval (list 'let org-local-vars
+ (list 'call-interactively (list 'quote cmd)))))
+
+;;;; Archiving
+
+(defalias 'org-advertized-archive-subtree 'org-archive-subtree)
+
+(defun org-archive-subtree (&optional find-done)
+ "Move the current subtree to the archive.
+The archive can be a certain top-level heading in the current file, or in
+a different file. The tree will be moved to that location, the subtree
+heading be marked DONE, and the current time will be added.
+
+When called with prefix argument FIND-DONE, find whole trees without any
+open TODO items and archive them (after getting confirmation from the user).
+If the cursor is not at a headline when this comand is called, try all level
+1 trees. If the cursor is on a headline, only try the direct children of
+this heading."
+ (interactive "P")
+ (if find-done
+ (org-archive-all-done)
+ ;; Save all relevant TODO keyword-relatex variables
+
+ (let ((tr-org-todo-line-regexp org-todo-line-regexp) ; keep despite compiler
+ (tr-org-todo-keywords-1 org-todo-keywords-1)
+ (tr-org-todo-kwd-alist org-todo-kwd-alist)
+ (tr-org-done-keywords org-done-keywords)
+ (tr-org-todo-regexp org-todo-regexp)
+ (tr-org-todo-line-regexp org-todo-line-regexp)
+ (tr-org-odd-levels-only org-odd-levels-only)
+ (this-buffer (current-buffer))
+ (org-archive-location org-archive-location)
+ (re "^#\\+ARCHIVE:[ \t]+\\(\\S-.*\\S-\\)[ \t]*$")
+ ;; start of variables that will be used for saving context
+ ;; The compiler complains about them - keep them anyway!
+ (file (abbreviate-file-name (buffer-file-name)))
+ (olpath (mapconcat 'identity (org-get-outline-path) "/"))
+ (time (format-time-string
+ (substring (cdr org-time-stamp-formats) 1 -1)
+ (current-time)))
+ afile heading buffer level newfile-p
+ category todo priority
+ ;; start of variables that will be used for savind context
+ ltags itags prop)
+
+ ;; Try to find a local archive location
+ (save-excursion
+ (save-restriction
+ (widen)
+ (setq prop (org-entry-get nil "ARCHIVE" 'inherit))
+ (if (and prop (string-match "\\S-" prop))
+ (setq org-archive-location prop)
+ (if (or (re-search-backward re nil t)
+ (re-search-forward re nil t))
+ (setq org-archive-location (match-string 1))))))
+
+ (if (string-match "\\(.*\\)::\\(.*\\)" org-archive-location)
+ (progn
+ (setq afile (format (match-string 1 org-archive-location)
(file-name-nondirectory buffer-file-name))
heading (match-string 2 org-archive-location)))
(error "Invalid `org-archive-location'"))
- (if (> (length file) 0)
- (setq newfile-p (not (file-exists-p file))
- buffer (find-file-noselect file))
+ (if (> (length afile) 0)
+ (setq newfile-p (not (file-exists-p afile))
+ buffer (find-file-noselect afile))
(setq buffer (current-buffer)))
(unless buffer
- (error "Cannot access file \"%s\"" file))
+ (error "Cannot access file \"%s\"" afile))
(if (and (> (length heading) 0)
(string-match "^\\*+" heading))
(setq level (match-end 0))
(setq heading nil level 0))
(save-excursion
+ (org-back-to-heading t)
+ ;; Get context information that will be lost by moving the tree
+ (org-refresh-category-properties)
+ (setq category (org-get-category)
+ todo (and (looking-at org-todo-line-regexp)
+ (match-string 2))
+ priority (org-get-priority (if (match-end 3) (match-string 3) ""))
+ ltags (org-get-tags)
+ itags (org-delete-all ltags (org-get-tags-at)))
+ (setq ltags (mapconcat 'identity ltags " ")
+ itags (mapconcat 'identity itags " "))
;; We first only copy, in case something goes wrong
;; we need to protect this-command, to avoid kill-region sets it,
;; which would lead to duplication of subtrees
;; Enforce org-mode for the archive buffer
(if (not (org-mode-p))
;; Force the mode for future visits.
- (let ((org-insert-mode-line-in-empty-file t))
+ (let ((org-insert-mode-line-in-empty-file t)
+ (org-inhibit-startup t))
(call-interactively 'org-mode)))
(when newfile-p
(goto-char (point-max))
(buffer-file-name this-buffer))))
;; Force the TODO keywords of the original buffer
(let ((org-todo-line-regexp tr-org-todo-line-regexp)
- (org-todo-keywords tr-org-todo-keywords)
- (org-todo-interpretation tr-org-todo-interpretation)
- (org-done-string tr-org-done-string)
+ (org-todo-keywords-1 tr-org-todo-keywords-1)
+ (org-todo-kwd-alist tr-org-todo-kwd-alist)
+ (org-done-keywords tr-org-done-keywords)
(org-todo-regexp tr-org-todo-regexp)
(org-todo-line-regexp tr-org-todo-line-regexp)
(org-odd-levels-only
- (if (local-variable-p 'org-odd-levels-only)
+ (if (local-variable-p 'org-odd-levels-only (current-buffer))
org-odd-levels-only
tr-org-odd-levels-only)))
(goto-char (point-min))
+ (show-all)
(if heading
(progn
(if (re-search-forward
- (concat "\\(^\\|\r\\)"
- (regexp-quote heading) "[ \t]*\\(:[a-zA-Z0-9_@:]+:\\)?[ \t]*\\($\\|\r\\)")
+ (concat "^" (regexp-quote heading)
+ (org-re "[ \t]*\\(:[[:alnum:]_@:]+:\\)?[ \t]*\\($\\|\r\\)"))
nil t)
(goto-char (match-end 0))
;; Heading not found, just insert it at the end
;; No specific heading, just go to end of file.
(goto-char (point-max)) (insert "\n"))
;; Paste
- (org-paste-subtree (org-get-legal-level level 1))
- ;; Mark the entry as done, i.e. set to last work in org-todo-keywords
- (if org-archive-mark-done
- (let (org-log-done)
- (org-todo (length org-todo-keywords))))
- ;; Move cursor to right after the TODO keyword
- (when org-archive-stamp-time
- (beginning-of-line 1)
- (looking-at org-todo-line-regexp)
- (goto-char (or (match-end 2) (match-beginning 3)))
- (org-insert-time-stamp (org-current-time) t t "(" ")"))
- ;; Save the buffer, if it is not the same buffer.
- (if (not (eq this-buffer buffer)) (save-buffer))))
+ (org-paste-subtree (org-get-valid-level level 1))
+
+ ;; Mark the entry as done
+ (when (and org-archive-mark-done
+ (looking-at org-todo-line-regexp)
+ (or (not (match-end 2))
+ (not (member (match-string 2) org-done-keywords))))
+ (let (org-log-done org-todo-log-states)
+ (org-todo
+ (car (or (member org-archive-mark-done org-done-keywords)
+ org-done-keywords)))))
+
+ ;; Add the context info
+ (when org-archive-save-context-info
+ (let ((l org-archive-save-context-info) e n v)
+ (while (setq e (pop l))
+ (when (and (setq v (symbol-value e))
+ (stringp v) (string-match "\\S-" v))
+ (setq n (concat "ARCHIVE_" (upcase (symbol-name e))))
+ (org-entry-put (point) n v)))))
+
+ ;; Save and kill the buffer, if it is not the same buffer.
+ (if (not (eq this-buffer buffer))
+ (progn (save-buffer) (kill-buffer buffer)))))
;; Here we are back in the original buffer. Everything seems to have
;; worked. So now cut the tree and finish up.
(let (this-command) (org-cut-subtree))
(message "Subtree archived %s"
(if (eq this-buffer buffer)
(concat "under heading: " heading)
- (concat "in file: " (abbreviate-file-name file)))))))
+ (concat "in file: " (abbreviate-file-name afile)))))))
+
+(defun org-refresh-category-properties ()
+ "Refresh category text properties in teh buffer."
+ (let ((def-cat (cond
+ ((null org-category)
+ (if buffer-file-name
+ (file-name-sans-extension
+ (file-name-nondirectory buffer-file-name))
+ "???"))
+ ((symbolp org-category) (symbol-name org-category))
+ (t org-category)))
+ beg end cat pos optionp)
+ (org-unmodified
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (put-text-property (point) (point-max) 'org-category def-cat)
+ (while (re-search-forward
+ "^\\(#\\+CATEGORY:\\|[ \t]*:CATEGORY:\\)\\(.*\\)" nil t)
+ (setq pos (match-end 0)
+ optionp (equal (char-after (match-beginning 0)) ?#)
+ cat (org-trim (match-string 2)))
+ (if optionp
+ (setq beg (point-at-bol) end (point-max))
+ (org-back-to-heading t)
+ (setq beg (point) end (org-end-of-subtree t t)))
+ (put-text-property beg end 'org-category cat)
+ (goto-char pos)))))))
(defun org-archive-all-done (&optional tag)
"Archive sublevels of the current tree without open TODO items.
(progn
(setq re1 (concat "^" (regexp-quote
(make-string
- (1+ (- (match-end 0) (match-beginning 0)))
+ (1+ (- (match-end 0) (match-beginning 0) 1))
?*))
" "))
(move-marker begm (point))
(goto-char end)))))
(message "%d trees archived" cntarch)))
+(defun org-cycle-hide-drawers (state)
+ "Re-hide all drawers after a visibility state change."
+ (when (and (org-mode-p)
+ (not (memq state '(overview folded))))
+ (save-excursion
+ (let* ((globalp (memq state '(contents all)))
+ (beg (if globalp (point-min) (point)))
+ (end (if globalp (point-max) (org-end-of-subtree t))))
+ (goto-char beg)
+ (while (re-search-forward org-drawer-regexp end t)
+ (org-flag-drawer t))))))
+
+(defun org-flag-drawer (flag)
+ (save-excursion
+ (beginning-of-line 1)
+ (when (looking-at "^[ \t]*:[a-zA-Z][a-zA-Z0-9]*:")
+ (let ((b (match-end 0))
+ (outline-regexp org-outline-regexp))
+ (if (re-search-forward
+ "^[ \t]*:END:"
+ (save-excursion (outline-next-heading) (point)) t)
+ (outline-flag-region b (point-at-eol) flag)
+ (error ":END: line missing"))))))
+
(defun org-cycle-hide-archived-subtrees (state)
"Re-hide all archived subtrees after a visibility state change."
(when (and (not org-cycle-open-archived-trees)
(org-hide-archived-subtrees beg end)
(goto-char beg)
(if (looking-at (concat ".*:" org-archive-tag ":"))
- (message (substitute-command-keys
- "Subtree is archived and stays closed. Use \\[org-force-cycle-archived] to cycle it anyway.")))))))
+ (message "%s" (substitute-command-keys
+ "Subtree is archived and stays closed. Use \\[org-force-cycle-archived] to cycle it anyway.")))))))
(defun org-force-cycle-archived ()
"Cycle subtree even if it is archived."
(defun org-toggle-tag (tag &optional onoff)
"Toggle the tag TAG for the current line.
If ONOFF is `on' or `off', don't toggle but set to this state."
- (unless (org-on-heading-p) (error "Not on headling"))
+ (unless (org-on-heading-p t) (error "Not on headling"))
(let (res current)
(save-excursion
(beginning-of-line)
- (if (re-search-forward "[ \t]:\\([a-zA-Z0-9_@:]+\\):[ \t]*$"
+ (if (re-search-forward (org-re "[ \t]:\\([[:alnum:]_@:]+\\):[ \t]*$")
(point-at-eol) t)
(progn
(setq current (match-string 1))
(setq res t)
(push tag current))))
(end-of-line 1)
- (when current
- (insert " :" (mapconcat 'identity (nreverse current) ":") ":"))
- (org-set-tags nil t))
+ (if current
+ (progn
+ (insert " :" (mapconcat 'identity (nreverse current) ":") ":")
+ (org-set-tags nil t))
+ (delete-horizontal-space))
+ (run-hooks 'org-after-tags-change-hook))
res))
(defun org-toggle-archive-tag (&optional arg)
"Table row types, non-nil only for the duration of a comand.")
(defvar org-table-current-begin-line nil
"Table begin line, non-nil only for the duration of a comand.")
+(defvar org-table-current-begin-pos nil
+ "Table begin position, non-nil only for the duration of a comand.")
(defvar org-table-dlines nil
"Vector of data line line numbers in the current table.")
(defvar org-table-hlines nil
"Regular expression for matching ranges in formulas.")
(defconst org-table-range-regexp2
- "@\\([-+]?I*[-+]?[0-9]*\\)?\\(\\$[-+]?[a-zA-Z0-9]+\\)?\\(\\.\\.@?\\([-+]?I*[-+]?[0-9]*\\)?\\(\\$[-+]?[a-zA-Z0-9]+\\)?\\)?\\|\\$[a-zA-Z0-9]+\\.\\.\\$[a-zA-Z0-9]+"
- "Regular expression to recognize ranges in formulas for highlighting.")
+ (concat
+ "\\(" "@[-0-9I$&]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\|" "\\$[a-zA-Z0-9]+" "\\)"
+ "\\.\\."
+ "\\(" "@?[-0-9I$&]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\|" "\\$[a-zA-Z0-9]+" "\\)")
+ "Match a range for reference display.")
-(defvar org-inhibit-highlight-removal nil)
+(defconst org-table-translate-regexp
+ (concat "\\(" "@[-0-9I$]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\)")
+ "Match a reference that needs translation, for reference display.")
+(defvar org-inhibit-highlight-removal nil) ; dynamically scoped param
(defun org-table-create-with-table.el ()
"Use the table.el package to insert a new table.
(defun org-table-create-or-convert-from-region (arg)
"Convert region to table, or create an empty table.
-If there is an active region, convert it to a table. If there is no such
-region, create an empty table."
+If there is an active region, convert it to a table, using the function
+`org-table-convert-region'. See the documentation of that function
+to learn how the prefix argument is interpreted to determine the field
+separator.
+If there is no such region, create an empty table with `org-table-create'."
(interactive "P")
(if (org-region-active-p)
(org-table-convert-region (region-beginning) (region-end) arg)
(goto-char pos)))
(org-table-align)))
-(defun org-table-convert-region (beg0 end0 &optional nspace)
+(defun org-table-convert-region (beg0 end0 &optional separator)
"Convert region to a table.
The region goes from BEG0 to END0, but these borders will be moved
slightly, to make sure a beginning of line in the first line is included.
-When NSPACE is non-nil, it indicates the minimum number of spaces that
-separate columns (default: just one space)."
+
+SEPARATOR specifies the field separator in the lines. It can have the
+following values:
+
+'(4) Use the comma as a field separator
+'(16) Use a TAB as field separator
+integer When a number, use that many spaces as field separator
+nil When nil, the command tries to be smart and figure out the
+ separator in the following way:
+ - when each line contains a TAB, assume TAB-separated material
+ - when each line contains a comme, assume CSV material
+ - else, assume one or more SPACE charcters as separator."
(interactive "rP")
(let* ((beg (min beg0 end0))
(end (max beg0 end0))
- (tabsep t)
re)
(goto-char beg)
(beginning-of-line 1)
(goto-char end)
(if (bolp) (backward-char 1) (end-of-line 1))
(setq end (move-marker (make-marker) (point)))
- ;; Lets see if this is tab-separated material. If every nonempty line
- ;; contains a tab, we will assume that it is tab-separated material
- (if nspace
- (setq tabsep nil)
+ ;; Get the right field separator
+ (unless separator
(goto-char beg)
- (and (re-search-forward "^[^\n\t]+$" end t) (setq tabsep nil)))
- (if nspace (setq tabsep nil))
- (if tabsep
- (setq re "^\\|\t")
- (setq re (format "^ *\\| *\t *\\| \\{%d,\\}"
- (max 1 (prefix-numeric-value nspace)))))
+ (setq separator
+ (cond
+ ((not (re-search-forward "^[^\n\t]+$" end t)) '(16))
+ ((not (re-search-forward "^[^\n,]+$" end t)) '(4))
+ (t 1))))
+ (setq re (cond
+ ((equal separator '(4)) "^\\|\"?[ \t]*,[ \t]*\"?")
+ ((equal separator '(16)) "^\\|\t")
+ ((integerp separator)
+ (format "^ *\\| *\t *\\| \\{%d,\\}" separator))
+ (t (error "This should not happen"))))
(goto-char beg)
(while (re-search-forward re end t)
(replace-match "| " t t))
(make-string sp2 ?\ ) "%%%s%ds" (make-string sp1 ?\ ) "|"))
(hfmt1 (concat
(make-string sp2 ?-) "%s" (make-string sp1 ?-) "+"))
- emptystrings links dates narrow fmax f1 len c e)
+ emptystrings links dates emph narrow fmax f1 len c e)
(untabify beg end)
(remove-text-properties beg end '(org-cwidth t org-dwidth t display t))
;; Check if we have links or dates
(goto-char beg)
(setq links (re-search-forward org-bracket-link-regexp end t))
(goto-char beg)
+ (setq emph (and org-hide-emphasis-markers
+ (re-search-forward org-emph-re end t)))
+ (goto-char beg)
(setq dates (and org-display-custom-times
(re-search-forward org-ts-regexp-both end t)))
;; Make sure the link properties are right
(when links (goto-char beg) (while (org-activate-bracket-links end)))
;; Make sure the date properties are right
(when dates (goto-char beg) (while (org-activate-dates end)))
+ (when emph (goto-char beg) (while (org-do-emphasis-faces end)))
;; Check if we are narrowing any columns
(goto-char beg)
;; With invisible characters, `format' does not get the field width right
;; So we need to make these fields wide by hand.
- (when links
+ (when (or links emph)
(loop for i from 0 upto (1- maxfields) do
(setq len (nth i lengths))
(loop for j from 0 upto (1- (length fields)) do
(setq c (nthcdr i (car (nthcdr j fields))))
(if (and (stringp (car c))
- (string-match org-bracket-link-regexp (car c))
+ (text-property-any 0 (length (car c)) 'invisible 'org-link (car c))
+; (string-match org-bracket-link-regexp (car c))
(< (org-string-width (car c)) len))
(setcar c (concat (car c) (make-string (- len (org-string-width (car c))) ?\ )))))))
(setq n (concat new "|") org-table-may-need-update t)))
(or (equal n o)
(let (org-table-may-need-update)
- (replace-match n))))
+ (replace-match n t t))))
(setq org-table-may-need-update t))
(goto-char pos))))))
the cursor is moved with it. Therefore, repeating this command causes the
column to be filled row-by-row.
If the variable `org-table-copy-increment' is non-nil and the field is an
-integer, it will be incremented while copying."
+integer or a timestamp, it will be incremented while copying. In the case of
+a timestamp, if the cursor is on the year, change the year. If it is on the
+month or the day, change that. Point will stay on the current date field
+in order to easily repeat the interval."
(interactive "p")
(let* ((colpos (org-table-current-column))
+ (col (current-column))
(field (org-table-get-field))
(non-empty (string-match "[^ \t]" field))
(beg (org-table-begin))
(string-match "^[0-9]+$" txt))
(setq txt (format "%d" (+ (string-to-number txt) 1))))
(insert txt)
- (org-table-maybe-recalculate-line)
- (org-table-align))
+ (move-to-column col)
+ (if (and org-table-copy-increment (org-at-timestamp-p t))
+ (org-timestamp-up 1)
+ (org-table-maybe-recalculate-line))
+ (org-table-align)
+ (move-to-column col))
(error "No non-empty field found"))))
(defun org-table-check-inside-data-field ()
val)
(forward-char 1) ""))
-
(defun org-table-field-info (arg)
"Show info about the current field, and highlight any reference at point."
(interactive "P")
(eql (org-table-get-stored-formulas))
(dline (org-table-current-dline))
(ref (format "@%d$%d" dline col))
+ (ref1 (org-table-convert-refs-to-an ref))
(fequation (or (assoc name eql) (assoc ref eql)))
- (cequation (assoc (int-to-string col) eql)))
+ (cequation (assoc (int-to-string col) eql))
+ (eqn (or fequation cequation)))
(goto-char pos)
(condition-case nil
- (org-show-reference 'local)
+ (org-table-show-reference 'local)
(error nil))
- (message "line @%d, col $%s%s, ref @%d$%d%s%s"
+ (message "line @%d, col $%s%s, ref @%d$%d or %s%s%s"
dline col
(if cname (concat " or $" cname) "")
- dline col
+ dline col ref1
(if name (concat " or $" name) "")
;; FIXME: formula info not correct if special table line
- (if (or fequation cequation)
- (concat ", " (if fequation "field" "column")
- " formula applies" "")
+ (if eqn
+ (concat ", formula: "
+ (org-table-formula-to-user
+ (concat
+ (if (string-match "^[$@]"(car eqn)) "" "$")
+ (car eqn) "=" (cdr eqn))))
"")))))
(defun org-table-current-column ()
(org-table-align))
(org-table-fix-formulas "@" nil (1- (org-table-current-dline)) 1)))
-(defun org-table-insert-hline (&optional arg)
+(defun org-table-insert-hline (&optional above)
"Insert a horizontal-line below the current line into the table.
-With prefix ARG, insert above the current line."
+With prefix ABOVE, insert above the current line."
(interactive "P")
(if (not (org-at-table-p))
(error "Not at a table"))
(concat "+" (make-string (- (match-end 1) (match-beginning 1))
?-) "|") t t line)))
(and (string-match "\\+" line) (setq line (replace-match "|" t t line)))
- (beginning-of-line (if arg 1 2))
+ (beginning-of-line (if above 1 2))
(insert line "\n")
- (beginning-of-line (if arg 1 -1))
+ (beginning-of-line (if above 1 -1))
(move-to-column col)
(and org-table-overlay-coordinates (org-table-align))))
+(defun org-table-hline-and-move (&optional same-column)
+ "Insert a hline and move to the row below that line."
+ (interactive "P")
+ (let ((col (org-table-current-column)))
+ (org-table-maybe-eval-formula)
+ (org-table-maybe-recalculate-line)
+ (org-table-insert-hline)
+ (end-of-line 2)
+ (if (looking-at "\n[ \t]*|-")
+ (progn (insert "\n|") (org-table-align))
+ (org-table-next-field))
+ (if same-column (org-table-goto-column col))))
+
(defun org-table-clean-line (s)
"Convert a table line S into a string with only \"|\" and space.
In particular, this does handle wide and invisible characters."
(org-table-fix-formulas "@" (list (cons (number-to-string dline) "INVALID"))
dline -1 dline)))
-
(defun org-table-sort-lines (with-case &optional sorting-type)
"Sort table lines according to the column at point.
(setq beg (point-at-bol 1)))
(goto-char pos)
(if (re-search-forward org-table-hline-regexp tend t)
- (setq beg (point-at-bol 0))
+ (setq end (point-at-bol 1))
(goto-char tend)
(setq end (point-at-bol))))
(setq beg (move-marker (make-marker) beg)
(skip-chars-backward "^|")
(setq ecol (1- (current-column)))
(org-table-goto-column column)
- (setq lns (mapcar (lambda(x) (cons (org-trim (substring x bcol ecol)) x))
+ (setq lns (mapcar (lambda(x) (cons
+ (org-sort-remove-invisible
+ (nth (1- column)
+ (org-split-string x "[ \t]*|[ \t]*")))
+ x))
(org-split-string (buffer-substring beg end) "\n")))
(setq lns (org-do-sort lns "Table" with-case sorting-type))
(delete-region beg end)
(org-table-goto-column thiscol)
(message "%d lines sorted, based on column %d" (length lns) column)))
+;; FIXME: maybe we will not need this? Table sorting is broken....
+(defun org-sort-remove-invisible (s)
+ (remove-text-properties 0 (length s) org-rm-props s)
+ (while (string-match org-bracket-link-regexp s)
+ (setq s (replace-match (if (match-end 2)
+ (match-string 3 s)
+ (match-string 1 s)) t t s)))
+ s)
+
(defun org-table-cut-region (beg end)
"Copy region in table to the clipboard and blank all relevant fields."
(interactive "r")
(org-table-goto-column ccol)
(org-table-paste-rectangle))
;; No region, split the current field at point
+ (unless (org-get-alist-option org-M-RET-may-split-line 'table)
+ (skip-chars-forward "^\r\n|"))
(if arg
;; combine with field above
(let ((s (org-table-blank-field))
(insert " " (org-trim s))
(org-table-align))
;; split field
- (when (looking-at "\\([^|]+\\)+|")
- (let ((s (match-string 1)))
- (replace-match " |")
- (goto-char (match-beginning 0))
- (org-table-next-row)
- (insert (org-trim s) " ")
- (org-table-align))))))
+ (if (looking-at "\\([^|]+\\)+|")
+ (let ((s (match-string 1)))
+ (replace-match " |")
+ (goto-char (match-beginning 0))
+ (org-table-next-row)
+ (insert (org-trim s) " ")
+ (org-table-align))
+ (org-table-next-row)))))
(defvar org-field-marker nil)
(field (org-table-get-field))
(cw (current-window-configuration))
p)
- (switch-to-buffer-other-window "*Org tmp*")
+ (org-switch-to-buffer-other-window "*Org tmp*")
(erase-buffer)
(insert "#\n# Edit field and finish with C-c C-c\n#\n")
- (org-mode)
+ (let ((org-inhibit-startup t)) (org-mode))
(goto-char (setq p (point-max)))
(insert (org-trim field))
(remove-text-properties p (point-max)
'(invisible t org-cwidth t display t
intangible t))
(goto-char p)
- (org-set-local 'org-finish-function
- 'org-table-finish-edit-field)
+ (org-set-local 'org-finish-function 'org-table-finish-edit-field)
(org-set-local 'org-window-configuration cw)
(org-set-local 'org-field-marker pos)
(message "Edit and finish with C-c C-c"))))
(defun org-trim (s)
"Remove whitespace at beginning and end of string."
- (if (string-match "^[ \t]+" s) (setq s (replace-match "" t t s)))
- (if (string-match "[ \t]+$" s) (setq s (replace-match "" t t s)))
+ (if (string-match "\\`[ \t\n\r]+" s) (setq s (replace-match "" t t s)))
+ (if (string-match "[ \t\n\r]+\\'" s) (setq s (replace-match "" t t s)))
s)
(defun org-wrap (string &optional width lines)
((equal n 0) nil)
(t n))))
-(defun org-table-current-field-formula ()
+(defun org-table-current-field-formula (&optional key noerror)
"Return the formula active for the current field.
-Assumes that specials are in place."
+Assumes that specials are in place.
+If KEY is given, return the key to this formula.
+Otherwise return the formula preceeded with \"=\" or \":=\"."
(let* ((name (car (rassoc (list (org-current-line)
(org-table-current-column))
org-table-named-field-locations)))
(col (org-table-current-column))
(scol (int-to-string col))
(ref (format "@%d$%d" (org-table-current-dline) col))
- (stored-list (org-table-get-stored-formulas))
+ (stored-list (org-table-get-stored-formulas noerror))
(ass (or (assoc name stored-list)
(assoc ref stored-list)
(assoc scol stored-list))))
- (if ass (concat (if (string-match "^[0-9]+$" (car ass)) "=" ":=")
- (cdr ass)))))
+ (if key
+ (car ass)
+ (if ass (concat (if (string-match "^[0-9]+$" (car ass)) "=" ":=")
+ (cdr ass))))))
(defun org-table-get-formula (&optional equation named)
"Read a formula from the minibuffer, offer stored formula as default.
stored)
((stringp equation)
equation)
- (t (read-string
- (format "%s formula $%s=" (if named "Field" "Column") scol)
- (or stored "") 'org-table-formula-history
- ;stored
- ))))
+ (t (org-table-formula-from-user
+ (read-string
+ (org-table-formula-to-user
+ (format "%s formula %s%s="
+ (if named "Field" "Column")
+ (if (member (string-to-char scol) '(?$ ?@)) "" "$")
+ scol))
+ (if stored (org-table-formula-to-user stored) "")
+ 'org-table-formula-history
+ )))))
mustsave)
(when (not (string-match "\\S-" eq))
;; remove formula
(defun org-table-store-formulas (alist)
"Store the list of formulas below the current table."
- (setq alist (sort alist (lambda (a b) (string< (car a) (car b)))))
+ (setq alist (sort alist 'org-table-formula-less-p))
(save-excursion
(goto-char (org-table-end))
(if (looking-at "\\([ \t]*\n\\)*#\\+TBLFM:\\(.*\n?\\)")
alist "::")
"\n")))
-(defun org-table-get-stored-formulas ()
+(defsubst org-table-formula-make-cmp-string (a)
+ (when (string-match "^\\(@\\([0-9]+\\)\\)?\\(\\$?\\([0-9]+\\)\\)?\\(\\$?[a-zA-Z0-9]+\\)?" a)
+ (concat
+ (if (match-end 2) (format "@%05d" (string-to-number (match-string 2 a))) "")
+ (if (match-end 4) (format "$%05d" (string-to-number (match-string 4 a))) "")
+ (if (match-end 5) (concat "@@" (match-string 5 a))))))
+
+(defun org-table-formula-less-p (a b)
+ "Compare two formulas for sorting."
+ (let ((as (org-table-formula-make-cmp-string (car a)))
+ (bs (org-table-formula-make-cmp-string (car b))))
+ (and as bs (string< as bs))))
+
+(defun org-table-get-stored-formulas (&optional noerror)
"Return an alist with the stored formulas directly after current table."
(interactive)
(let (scol eq eq-alist strings string seen)
eq (match-string 3 string)
eq-alist (cons (cons scol eq) eq-alist))
(if (member scol seen)
- (error "Double definition `$%s=' in TBLFM line, please fix by hand" scol)
+ (if noerror
+ (progn
+ (message "Double definition `$%s=' in TBLFM line, please fix by hand" scol)
+ (ding)
+ (sit-for 2))
+ (error "Double definition `$%s=' in TBLFM line, please fix by hand" scol))
(push scol seen))))))
(nreverse eq-alist)))
org-table-local-parameters nil
org-table-named-field-locations nil
org-table-current-begin-line nil
+ org-table-current-begin-pos nil
org-table-current-line-types nil)
(goto-char beg)
(when (re-search-forward "^[ \t]*| *! *\\(|.*\\)" end t)
(while (re-search-forward "^[ \t]*| *\\$ *\\(|.*\\)" end t)
(setq fields (org-split-string (match-string 1) " *| *"))
(while (setq field (pop fields))
- (if (string-match "^\\([a-zA-Z][a-zA-Z0-9]*\\|%\\) *= *\\(.*\\)" field)
+ (if (string-match "^\\([a-zA-Z][_a-zA-Z0-9]*\\|%\\) *= *\\(.*\\)" field)
(push (cons (match-string 1 field) (match-string 2 field))
org-table-local-parameters))))
(goto-char beg)
;; Analyse the line types
(goto-char beg)
(setq org-table-current-begin-line (org-current-line)
+ org-table-current-begin-pos (point)
l org-table-current-begin-line)
(while (looking-at "[ \t]*|\\(-\\)?")
(push (if (match-end 1) 'hline 'dline) types)
org-table-dlines (apply 'vector (cons nil (nreverse dlines)))
org-table-hlines (apply 'vector (cons nil (nreverse hlines)))))))
-(defun org-this-word ()
- ;; Get the current word
- (save-excursion
- (let ((beg (progn (skip-chars-backward "^ \t\n") (point)))
- (end (progn (skip-chars-forward "^ \t\n") (point))))
- (buffer-substring-no-properties beg end))))
-
(defun org-table-maybe-eval-formula ()
"Check if the current field starts with \"=\" or \":=\".
If yes, store the formula and apply it."
eq (match-string 1 field))
(if (or (fboundp 'calc-eval)
(equal (substring eq 0 (min 2 (length eq))) "'("))
- (org-table-eval-formula (if named '(4) nil) eq)
+ (org-table-eval-formula (if named '(4) nil)
+ (org-table-formula-from-user eq))
(error "Calc does not seem to be installed, and is needed to evaluate the formula"))))))
(defvar org-recalc-commands nil
(goto-line l1)))
(if (not (= epos (point-at-eol))) (org-table-align))
(goto-line l)
- (and (interactive-p) (message (cdr (assoc new org-recalc-marks))))))
+ (and (interactive-p) (message "%s" (cdr (assoc new org-recalc-marks))))))
(defun org-table-maybe-recalculate-line ()
"Recompute the current line if marked for it, and if we haven't just done it."
When called with two `C-u' prefixes, insert the active equation
for the field back into the current field, so that it can be
-edited there. This is useful in order to use \\[org-show-reference]
+edited there. This is useful in order to use \\[org-table-show-reference]
to check the referenced fields.
When called, the command first prompts for a formula, which is read in
(modes (copy-sequence org-calc-default-modes))
(numbers nil) ; was a variable, now fixed default
(keep-empty nil)
- n form form0 bw fmt x ev orig c lispp)
+ n form form0 bw fmt x ev orig c lispp literal)
;; Parse the format string. Since we have a lot of modes, this is
;; a lot of work. However, I think calc still uses most of the time.
(if (string-match ";" formula)
(if (string-match "[NT]" fmt)
(setq numbers (equal (match-string 0 fmt) "N")
fmt (replace-match "" t t fmt)))
+ (if (string-match "L" fmt)
+ (setq literal t
+ fmt (replace-match "" t t fmt)))
(if (string-match "E" fmt)
(setq keep-empty t
fmt (replace-match "" t t fmt)))
(org-no-properties
(buffer-substring (point-at-bol) (point-at-eol)))
" *| *"))
- (if numbers
+ (if (eq numbers t)
(setq fields (mapcar
(lambda (x) (number-to-string (string-to-number x)))
fields)))
(setq ndown (1- ndown))
(setq form (copy-sequence formula)
lispp (and (> (length form) 2)(equal (substring form 0 2) "'(")))
+ (if (and lispp literal) (setq lispp 'literal))
;; Check for old vertical references
(setq form (org-rewrite-old-row-references form))
;; Insert complex ranges
t t form)))
(setq form0 form)
;; Insert the references to fields in same row
- (while (string-match "\\$\\([0-9]+\\)?" form)
- (setq n (if (match-beginning 1)
- (string-to-number (match-string 1 form))
- n0)
- x (nth (1- n) fields))
+ (while (string-match "\\$\\([0-9]+\\)" form)
+ (setq n (string-to-number (match-string 1 form))
+ x (nth (1- (if (= n 0) n0 n)) fields))
(unless x (error "Invalid field specifier \"%s\""
(match-string 0 form)))
(setq form (replace-match
(save-match-data
(org-table-make-reference x nil numbers lispp))
t t form)))
+
(if lispp
(setq ev (condition-case nil
(eval (eval (read form)))
(or suppress-align (and org-table-may-need-update
(org-table-align))))))
+(defun org-table-put-field-property (prop value)
+ (save-excursion
+ (put-text-property (progn (skip-chars-backward "^|") (point))
+ (progn (skip-chars-forward "^|") (point))
+ prop value)))
+
(defun org-table-get-range (desc &optional tbeg col highlight)
"Get a calc vector from a column, accorting to descriptor DESC.
Optional arguments TBEG and COL can give the beginning of the table and
(goto-line r1)
(while (not (looking-at org-table-dataline-regexp))
(beginning-of-line 2))
- (prog1 (org-table-get-field c1)
+ (prog1 (org-trim (org-table-get-field c1))
(if highlight (org-table-highlight-rectangle (point) (point)))))
;; A range, return a vector
;; First sort the numbers to get a regular ractangle
(org-table-highlight-rectangle
beg (progn (skip-chars-forward "^|\n") (point))))
;; return string representation of calc vector
- (apply 'append (org-table-copy-region beg end))))))
+ (mapcar 'org-trim
+ (apply 'append (org-table-copy-region beg end)))))))
(defun org-table-get-descriptor-line (desc &optional cline bline table)
"Analyze descriptor DESC and retrieve the corresponding line number.
(setq i 0 hdir "+")
(if (eq (aref table 0) 'hline) (setq hn (1- hn)))))
(if (and (not hn) on (not odir))
- (error "should never happen");;(aref org-table-dlines on) FIXME
+ (error "should never happen");;(aref org-table-dlines on)
(if (and hn (> hn 0))
(setq i (org-find-row-type table i 'hline (equal hdir "-") nil hn)))
(if on
LISPP means to return something appropriate for a Lisp list."
(if (stringp elements) ; just a single val
(if lispp
- (prin1-to-string (if numbers (string-to-number elements) elements))
+ (if (eq lispp 'literal)
+ elements
+ (prin1-to-string (if numbers (string-to-number elements) elements)))
(if (equal elements "") (setq elements "0"))
(if numbers (number-to-string (string-to-number elements)) elements))
(unless keep-empty
elements))))
(setq elements (or elements '("0")))
(if lispp
- (mapconcat 'prin1-to-string
- (if numbers (mapcar 'string-to-number elements) elements)
- " ")
+ (mapconcat
+ (lambda (x)
+ (if (eq lispp 'literal)
+ x
+ (prin1-to-string (if numbers (string-to-number x) x))))
+ elements " ")
(concat "[" (mapconcat
(lambda (x)
(if numbers (number-to-string (string-to-number x)) x))
(line-re org-table-dataline-regexp)
(thisline (org-current-line))
(thiscol (org-table-current-column))
- beg end entry eqlnum eqlname eql (cnt 0) eq a name)
+ beg end entry eqlnum eqlname eqlname1 eql (cnt 0) eq a name)
;; Insert constants in all formulas
(setq eqlist
(mapcar (lambda (x)
end (move-marker (make-marker) (1+ (point-at-eol)))))
(goto-char beg)
(and all (message "Re-applying formulas to full table..."))
+
+ ;; First find the named fields, and mark them untouchanble
+ (remove-text-properties beg end '(org-untouchable t))
+ (while (setq eq (pop eqlname))
+ (setq name (car eq)
+ a (assoc name org-table-named-field-locations))
+ (and (not a)
+ (string-match "@\\([0-9]+\\)\\$\\([0-9]+\\)" name)
+ (setq a (list name
+ (aref org-table-dlines
+ (string-to-number (match-string 1 name)))
+ (string-to-number (match-string 2 name)))))
+ (when (and a (or all (equal (nth 1 a) thisline)))
+ (message "Re-applying formula to field: %s" name)
+ (goto-line (nth 1 a))
+ (org-table-goto-column (nth 2 a))
+ (push (append a (list (cdr eq))) eqlname1)
+ (org-table-put-field-property :org-untouchable t)))
+
+ ;; Now evauluate the column formulas, but skip fields covered by
+ ;; field formulas
+ (goto-char beg)
(while (re-search-forward line-re end t)
- (unless (string-match "^ *[_^!$] *$" (org-table-get-field 1))
+ (unless (string-match "^ *[_^!$/] *$" (org-table-get-field 1))
;; Unprotected line, recalculate
(and all (message "Re-applying formulas to full table...(line %d)"
(setq cnt (1+ cnt))))
(while (setq entry (pop eql))
(goto-line org-last-recalc-line)
(org-table-goto-column (string-to-number (car entry)) nil 'force)
- (org-table-eval-formula nil (cdr entry)
- 'noalign 'nocst 'nostore 'noanalysis))))
+ (unless (get-text-property (point) :org-untouchable)
+ (org-table-eval-formula nil (cdr entry)
+ 'noalign 'nocst 'nostore 'noanalysis)))))
+
+ ;; Now evaluate the field formulas
+ (while (setq eq (pop eqlname1))
+ (message "Re-applying formula to field: %s" (car eq))
+ (goto-line (nth 1 eq))
+ (org-table-goto-column (nth 2 eq))
+ (org-table-eval-formula nil (nth 3 eq) 'noalign 'nocst
+ 'nostore 'noanalysis))
+
(goto-line thisline)
(org-table-goto-column thiscol)
+ (remove-text-properties (point-min) (point-max) '(org-untouchable t))
(or noalign (and org-table-may-need-update (org-table-align))
(and all (message "Re-applying formulas to %d lines...done" cnt)))
- ;; Now do the named fields
- (while (setq eq (pop eqlname))
- (setq name (car eq)
- a (assoc name org-table-named-field-locations))
- (and (not a)
- (string-match "@\\([0-9]+\\)\\$\\([0-9]+\\)" name)
- (setq a
- (list
- name
- (aref org-table-dlines
- (string-to-number (match-string 1 name)))
- (string-to-number (match-string 2 name)))))
- (when (and a (or all (equal (nth 1 a) thisline)))
- (message "Re-applying formula to field: %s" name)
- (goto-line (nth 1 a))
- (org-table-goto-column (nth 2 a))
- (org-table-eval-formula nil (cdr eq) 'noalign 'nocst
- 'nostore 'noanalysis)))
+
;; back to initial position
(message "Re-applying formulas...done")
(goto-line thisline)
(defun org-table-formula-substitute-names (f)
"Replace $const with values in string F."
- (let ((start 0) a (f1 f))
+ (let ((start 0) a (f1 f) (pp (/= (string-to-char f) ?')))
;; First, check for column names
(while (setq start (string-match org-table-column-name-regexp f start))
(setq start (1+ start))
(setq f (replace-match (concat "$" (cdr a)) t t f)))
;; Parameters and constants
(setq start 0)
- (while (setq start (string-match "\\$\\([a-zA-Z][a-zA-Z0-9]*\\)" f start))
+ (while (setq start (string-match "\\$\\([a-zA-Z][_a-zA-Z0-9]*\\)" f start))
(setq start (1+ start))
(if (setq a (save-match-data
(org-table-get-constant (match-string 1 f))))
- (setq f (replace-match (concat "(" a ")") t t f))))
+ (setq f (replace-match
+ (concat (if pp "(") a (if pp ")")) t t f))))
(if org-table-formula-debug
(put-text-property 0 (length f) :orig-formula f1 f))
f))
"Find the value for a parameter or constant in a formula.
Parameters get priority."
(or (cdr (assoc const org-table-local-parameters))
+ (cdr (assoc const org-table-formula-constants-local))
(cdr (assoc const org-table-formula-constants))
(and (fboundp 'constants-get) (constants-get const))
+ (and (string= (substring const 0 (min 5 (length const))) "PROP_")
+ (org-entry-get nil (substring const 5) 'inherit))
"#UNDEFINED_NAME"))
-(defvar org-edit-formulas-map (make-sparse-keymap))
-(define-key org-edit-formulas-map "\C-c\C-c" 'org-finish-edit-formulas)
-(define-key org-edit-formulas-map "\C-c\C-q" 'org-abort-edit-formulas)
-(define-key org-edit-formulas-map "\C-c?" 'org-show-reference)
-(define-key org-edit-formulas-map [(shift up)] 'org-table-edit-line-up)
-(define-key org-edit-formulas-map [(shift down)] 'org-table-edit-line-down)
-(define-key org-edit-formulas-map [(shift left)] 'org-table-edit-backward-field)
-(define-key org-edit-formulas-map [(shift right)] 'org-table-edit-next-field)
-(define-key org-edit-formulas-map [(meta up)] 'org-table-edit-scroll-down)
-(define-key org-edit-formulas-map [(meta down)] 'org-table-edit-scroll)
-(define-key org-edit-formulas-map [(meta tab)] 'lisp-complete-symbol)
-(define-key org-edit-formulas-map "\M-\C-i" 'lisp-complete-symbol)
-(define-key org-edit-formulas-map [(tab)] 'org-edit-formula-lisp-indent)
-(define-key org-edit-formulas-map "\C-i" 'org-edit-formula-lisp-indent)
+(defvar org-table-fedit-map
+ (let ((map (make-sparse-keymap)))
+ (org-defkey map "\C-x\C-s" 'org-table-fedit-finish)
+ (org-defkey map "\C-c\C-s" 'org-table-fedit-finish)
+ (org-defkey map "\C-c\C-c" 'org-table-fedit-finish)
+ (org-defkey map "\C-c\C-q" 'org-table-fedit-abort)
+ (org-defkey map "\C-c?" 'org-table-show-reference)
+ (org-defkey map [(meta shift up)] 'org-table-fedit-line-up)
+ (org-defkey map [(meta shift down)] 'org-table-fedit-line-down)
+ (org-defkey map [(shift up)] 'org-table-fedit-ref-up)
+ (org-defkey map [(shift down)] 'org-table-fedit-ref-down)
+ (org-defkey map [(shift left)] 'org-table-fedit-ref-left)
+ (org-defkey map [(shift right)] 'org-table-fedit-ref-right)
+ (org-defkey map [(meta up)] 'org-table-fedit-scroll-down)
+ (org-defkey map [(meta down)] 'org-table-fedit-scroll)
+ (org-defkey map [(meta tab)] 'lisp-complete-symbol)
+ (org-defkey map "\M-\C-i" 'lisp-complete-symbol)
+ (org-defkey map [(tab)] 'org-table-fedit-lisp-indent)
+ (org-defkey map "\C-i" 'org-table-fedit-lisp-indent)
+ (org-defkey map "\C-c\C-r" 'org-table-fedit-toggle-ref-type)
+ (org-defkey map "\C-c}" 'org-table-fedit-toggle-coordinates)
+ map))
+
+(easy-menu-define org-table-fedit-menu org-table-fedit-map "Org Edit Formulas Menu"
+ '("Edit-Formulas"
+ ["Finish and Install" org-table-fedit-finish t]
+ ["Finish, Install, and Apply" (org-table-fedit-finish t) :keys "C-u C-c C-c"]
+ ["Abort" org-table-fedit-abort t]
+ "--"
+ ["Pretty-Print Lisp Formula" org-table-fedit-lisp-indent t]
+ ["Complete Lisp Symbol" lisp-complete-symbol t]
+ "--"
+ "Shift Reference at Point"
+ ["Up" org-table-fedit-ref-up t]
+ ["Down" org-table-fedit-ref-down t]
+ ["Left" org-table-fedit-ref-left t]
+ ["Right" org-table-fedit-ref-right t]
+ "-"
+ "Change Test Row for Column Formulas"
+ ["Up" org-table-fedit-line-up t]
+ ["Down" org-table-fedit-line-down t]
+ "--"
+ ["Scroll Table Window" org-table-fedit-scroll t]
+ ["Scroll Table Window down" org-table-fedit-scroll-down t]
+ ["Show Table Grid" org-table-fedit-toggle-coordinates
+ :style toggle :selected (with-current-buffer (marker-buffer org-pos)
+ org-table-overlay-coordinates)]
+ "--"
+ ["Standard Refs (B3 instead of @3$2)" org-table-fedit-toggle-ref-type
+ :style toggle :selected org-table-buffer-is-an]))
(defvar org-pos)
(defun org-table-edit-formulas ()
"Edit the formulas of the current table in a separate buffer."
(interactive)
+ (when (save-excursion (beginning-of-line 1) (looking-at "#\\+TBLFM"))
+ (beginning-of-line 0))
(unless (org-at-table-p) (error "Not at a table"))
(org-table-get-specials)
- (let ((eql (org-table-get-stored-formulas))
+ (let ((key (org-table-current-field-formula 'key 'noerror))
+ (eql (sort (org-table-get-stored-formulas 'noerror)
+ 'org-table-formula-less-p))
(pos (move-marker (make-marker) (point)))
+ (startline 1)
(wc (current-window-configuration))
- entry s)
- (switch-to-buffer-other-window "*Edit Formulas*")
+ (titles '((column . "# Column Formulas\n")
+ (field . "# Field Formulas\n")
+ (named . "# Named Field Formulas\n")))
+ entry s type title)
+ (org-switch-to-buffer-other-window "*Edit Formulas*")
(erase-buffer)
;; Keep global-font-lock-mode from turning on font-lock-mode
(let ((font-lock-global-modes '(not fundamental-mode)))
(org-set-local 'font-lock-global-modes (list 'not major-mode))
(org-set-local 'org-pos pos)
(org-set-local 'org-window-configuration wc)
- (use-local-map org-edit-formulas-map)
- (org-add-hook 'post-command-hook 'org-table-edit-formulas-post-command t t)
- (setq s "# `C-c C-c' to finish, `C-u C-c C-c' to also apply, `C-c C-q' to abort.
-# `TAB' to pretty-print Lisp expressions, `M-TAB' to complete List symbols
-# `M-up/down' to scroll table, `S-up/down' to change line for column formulas\n\n")
-
- (put-text-property 0 (length s) 'face 'font-lock-comment-face s)
- (insert s)
+ (use-local-map org-table-fedit-map)
+ (org-add-hook 'post-command-hook 'org-table-fedit-post-command t t)
+ (easy-menu-add org-table-fedit-menu)
+ (setq startline (org-current-line))
(while (setq entry (pop eql))
+ (setq type (cond
+ ((equal (string-to-char (car entry)) ?@) 'field)
+ ((string-match "^[0-9]" (car entry)) 'column)
+ (t 'named)))
+ (when (setq title (assq type titles))
+ (or (bobp) (insert "\n"))
+ (insert (org-add-props (cdr title) nil 'face font-lock-comment-face))
+ (setq titles (delq title titles)))
+ (if (equal key (car entry)) (setq startline (org-current-line)))
(setq s (concat (if (equal (string-to-char (car entry)) ?@) "" "$")
(car entry) " = " (cdr entry) "\n"))
(remove-text-properties 0 (length s) '(face nil) s)
(insert s))
- (goto-char (point-min))
- (message "Edit formulas and finish with `C-c C-c'.")))
+ (if (eq org-table-use-standard-references t)
+ (org-table-fedit-toggle-ref-type))
+ (goto-line startline)
+ (message "Edit formulas and finish with `C-c C-c'. See menu for more commands.")))
-(defun org-table-edit-formulas-post-command ()
+(defun org-table-fedit-post-command ()
(when (not (memq this-command '(lisp-complete-symbol)))
(let ((win (selected-window)))
(save-excursion
(condition-case nil
- (org-show-reference)
+ (org-table-show-reference)
(error nil))
(select-window win)))))
-(defun org-finish-edit-formulas (&optional arg)
+(defun org-table-formula-to-user (s)
+ "Convert a formula from internal to user representation."
+ (if (eq org-table-use-standard-references t)
+ (org-table-convert-refs-to-an s)
+ s))
+
+(defun org-table-formula-from-user (s)
+ "Convert a formula from user to internal representation."
+ (if org-table-use-standard-references
+ (org-table-convert-refs-to-rc s)
+ s))
+
+(defun org-table-convert-refs-to-rc (s)
+ "Convert spreadsheet references from AB7 to @7$28.
+Works for single references, but also for entire formulas and even the
+full TBLFM line."
+ (let ((start 0))
+ (while (string-match "\\<\\([a-zA-Z]+\\)\\([0-9]+\\>\\|&\\)\\|\\(;[^\r\n:]+\\)" s start)
+ (cond
+ ((match-end 3)
+ ;; format match, just advance
+ (setq start (match-end 0)))
+ ((and (> (match-beginning 0) 0)
+ (equal ?. (aref s (max (1- (match-beginning 0)) 0)))
+ (not (equal ?. (aref s (max (- (match-beginning 0) 2) 0)))))
+ ;; 3.e5 or something like this.
+ (setq start (match-end 0)))
+ (t
+ (setq start (match-beginning 0)
+ s (replace-match
+ (if (equal (match-string 2 s) "&")
+ (format "$%d" (org-letters-to-number (match-string 1 s)))
+ (format "@%d$%d"
+ (string-to-number (match-string 2 s))
+ (org-letters-to-number (match-string 1 s))))
+ t t s)))))
+ s))
+
+(defun org-table-convert-refs-to-an (s)
+ "Convert spreadsheet references from to @7$28 to AB7.
+Works for single references, but also for entire formulas and even the
+full TBLFM line."
+ (while (string-match "@\\([0-9]+\\)\\$\\([0-9]+\\)" s)
+ (setq s (replace-match
+ (format "%s%d"
+ (org-number-to-letters
+ (string-to-number (match-string 2 s)))
+ (string-to-number (match-string 1 s)))
+ t t s)))
+ (while (string-match "\\(^\\|[^0-9a-zA-Z]\\)\\$\\([0-9]+\\)" s)
+ (setq s (replace-match (concat "\\1"
+ (org-number-to-letters
+ (string-to-number (match-string 2 s))) "&")
+ t nil s)))
+ s)
+
+(defun org-letters-to-number (s)
+ "Convert a base 26 number represented by letters into an integer.
+For example: AB -> 28."
+ (let ((n 0))
+ (setq s (upcase s))
+ (while (> (length s) 0)
+ (setq n (+ (* n 26) (string-to-char s) (- ?A) 1)
+ s (substring s 1)))
+ n))
+
+(defun org-number-to-letters (n)
+ "Convert an integer into a base 26 number represented by letters.
+For example: 28 -> AB."
+ (let ((s ""))
+ (while (> n 0)
+ (setq s (concat (char-to-string (+ (mod (1- n) 26) ?A)) s)
+ n (/ (1- n) 26)))
+ s))
+
+(defun org-table-fedit-convert-buffer (function)
+ "Convert all references in this buffer, using FUNTION."
+ (let ((line (org-current-line)))
+ (goto-char (point-min))
+ (while (not (eobp))
+ (insert (funcall function (buffer-substring (point) (point-at-eol))))
+ (delete-region (point) (point-at-eol))
+ (or (eobp) (forward-char 1)))
+ (goto-line line)))
+
+(defun org-table-fedit-toggle-ref-type ()
+ "Convert all references in the buffer from B3 to @3$2 and back."
+ (interactive)
+ (org-set-local 'org-table-buffer-is-an (not org-table-buffer-is-an))
+ (org-table-fedit-convert-buffer
+ (if org-table-buffer-is-an
+ 'org-table-convert-refs-to-an 'org-table-convert-refs-to-rc))
+ (message "Reference type switched to %s"
+ (if org-table-buffer-is-an "A1 etc" "@row$column")))
+
+(defun org-table-fedit-ref-up ()
+ "Shift the reference at point one row/hline up."
+ (interactive)
+ (org-table-fedit-shift-reference 'up))
+(defun org-table-fedit-ref-down ()
+ "Shift the reference at point one row/hline down."
+ (interactive)
+ (org-table-fedit-shift-reference 'down))
+(defun org-table-fedit-ref-left ()
+ "Shift the reference at point one field to the left."
+ (interactive)
+ (org-table-fedit-shift-reference 'left))
+(defun org-table-fedit-ref-right ()
+ "Shift the reference at point one field to the right."
+ (interactive)
+ (org-table-fedit-shift-reference 'right))
+
+(defun org-table-fedit-shift-reference (dir)
+ (cond
+ ((org-at-regexp-p "\\(\\<[a-zA-Z]\\)&")
+ (if (memq dir '(left right))
+ (org-rematch-and-replace 1 (eq dir 'left))
+ (error "Cannot shift reference in this direction")))
+ ((org-at-regexp-p "\\(\\<[a-zA-Z]\\{1,2\\}\\)\\([0-9]+\\)")
+ ;; A B3-like reference
+ (if (memq dir '(up down))
+ (org-rematch-and-replace 2 (eq dir 'up))
+ (org-rematch-and-replace 1 (eq dir 'left))))
+ ((org-at-regexp-p
+ "\\(@\\|\\.\\.\\)\\([-+]?\\(I+\\>\\|[0-9]+\\)\\)\\(\\$\\([-+]?[0-9]+\\)\\)?")
+ ;; An internal reference
+ (if (memq dir '(up down))
+ (org-rematch-and-replace 2 (eq dir 'up) (match-end 3))
+ (org-rematch-and-replace 5 (eq dir 'left))))))
+
+(defun org-rematch-and-replace (n &optional decr hline)
+ "Re-match the group N, and replace it with the shifted refrence."
+ (or (match-end n) (error "Cannot shift reference in this direction"))
+ (goto-char (match-beginning n))
+ (and (looking-at (regexp-quote (match-string n)))
+ (replace-match (org-shift-refpart (match-string 0) decr hline)
+ t t)))
+
+(defun org-shift-refpart (ref &optional decr hline)
+ "Shift a refrence part REF.
+If DECR is set, decrease the references row/column, else increase.
+If HLINE is set, this may be a hline reference, it certainly is not
+a translation reference."
+ (save-match-data
+ (let* ((sign (string-match "^[-+]" ref)) n)
+
+ (if sign (setq sign (substring ref 0 1) ref (substring ref 1)))
+ (cond
+ ((and hline (string-match "^I+" ref))
+ (setq n (string-to-number (concat sign (number-to-string (length ref)))))
+ (setq n (+ n (if decr -1 1)))
+ (if (= n 0) (setq n (+ n (if decr -1 1))))
+ (if sign
+ (setq sign (if (< n 0) "-" "+") n (abs n))
+ (setq n (max 1 n)))
+ (concat sign (make-string n ?I)))
+
+ ((string-match "^[0-9]+" ref)
+ (setq n (string-to-number (concat sign ref)))
+ (setq n (+ n (if decr -1 1)))
+ (if sign
+ (concat (if (< n 0) "-" "+") (number-to-string (abs n)))
+ (number-to-string (max 1 n))))
+
+ ((string-match "^[a-zA-Z]+" ref)
+ (org-number-to-letters
+ (max 1 (+ (org-letters-to-number ref) (if decr -1 1)))))
+
+ (t (error "Cannot shift reference"))))))
+
+(defun org-table-fedit-toggle-coordinates ()
+ "Toggle the display of coordinates in the refrenced table."
+ (interactive)
+ (let ((pos (marker-position org-pos)))
+ (with-current-buffer (marker-buffer org-pos)
+ (save-excursion
+ (goto-char pos)
+ (org-table-toggle-coordinate-overlays)))))
+
+(defun org-table-fedit-finish (&optional arg)
"Parse the buffer for formula definitions and install them.
With prefix ARG, apply the new formulas to the table."
(interactive "P")
(org-table-remove-rectangle-highlight)
+ (if org-table-use-standard-references
+ (progn
+ (org-table-fedit-convert-buffer 'org-table-convert-refs-to-rc)
+ (setq org-table-buffer-is-an nil)))
(let ((pos org-pos) eql var form)
- (setq org-pos nil)
(goto-char (point-min))
(while (re-search-forward
"^\\(@[0-9]+\\$[0-9]+\\|\\$\\([a-zA-Z0-9]+\\)\\) *= *\\(.*\\(\n[ \t]+.*$\\)*\\)"
(setq var (if (match-end 2) (match-string 2) (match-string 1))
form (match-string 3))
(setq form (org-trim form))
- (while (string-match "[ \t]*\n[ \t]*" form)
- (setq form (replace-match " " t t form)))
- (push (cons var form) eql))
+ (when (not (equal form ""))
+ (while (string-match "[ \t]*\n[ \t]*" form)
+ (setq form (replace-match " " t t form)))
+ (when (assoc var eql)
+ (error "Double formulas for %s" var))
+ (push (cons var form) eql)))
+ (setq org-pos nil)
(set-window-configuration org-window-configuration)
(select-window (get-buffer-window (marker-buffer pos)))
(goto-char pos)
(org-table-recalculate 'all)
(message "New formulas installed - press C-u C-c C-c to apply."))))
-(defun org-abort-edit-formulas ()
+(defun org-table-fedit-abort ()
"Abort editing formulas, without installing the changes."
(interactive)
(org-table-remove-rectangle-highlight)
(move-marker pos nil)
(message "Formula editing aborted without installing changes")))
-(defun org-edit-formula-lisp-indent ()
+(defun org-table-fedit-lisp-indent ()
"Pretty-print and re-indent Lisp expressions in the Formula Editor."
(interactive)
(let ((pos (point)) beg end ind)
((looking-at "[ \t]")
(goto-char pos)
(call-interactively 'lisp-indent-line))
- ((looking-at "[$@0-9a-zA-Z]+ *= *[^ \t\n']") (goto-char pos))
+ ((looking-at "[$&@0-9a-zA-Z]+ *= *[^ \t\n']") (goto-char pos))
((not (fboundp 'pp-buffer))
(error "Cannot pretty-print. Command `pp-buffer' is not available."))
- ((looking-at "[$@0-9a-zA-Z]+ *= *'(")
+ ((looking-at "[$&@0-9a-zA-Z]+ *= *'(")
(goto-char (- (match-end 0) 2))
(setq beg (point))
(setq ind (make-string (current-column) ?\ ))
(defvar org-show-positions nil)
-(defun org-show-reference (&optional local)
+(defun org-table-show-reference (&optional local)
"Show the location/value of the $ expression at point."
(interactive)
(org-table-remove-rectangle-highlight)
var name e what match dest)
(if local (org-table-get-specials))
(setq what (cond
- ((org-at-regexp-p org-table-range-regexp2) 'range)
+ ((or (org-at-regexp-p org-table-range-regexp2)
+ (org-at-regexp-p org-table-translate-regexp)
+ (org-at-regexp-p org-table-range-regexp))
+ (setq match
+ (save-match-data
+ (org-table-convert-refs-to-rc (match-string 0))))
+ 'range)
((org-at-regexp-p "\\$[a-zA-Z][a-zA-Z0-9]*") 'name)
((org-at-regexp-p "\\$[0-9]+") 'column)
((not local) nil)
(t (error "No reference at point")))
- match (and what (match-string 0)))
+ match (and what (or match (match-string 0))))
(when (and match (not (equal (match-beginning 0) (point-at-bol))))
(org-table-add-rectangle-overlay (match-beginning 0) (match-end 0)
'secondary-selection))
(setq match (org-table-formula-substitute-names match)))
(unless local
(save-excursion
+ (end-of-line 1)
+ (re-search-backward "^\\S-" nil t)
(beginning-of-line 1)
- (when (looking-at "\\(\\$[0-9a-zA-Z]+\\|@[0-9]+\\$[0-9]+\\)=")
- (setq dest (match-string 1))
+ (when (looking-at "\\(\\$[0-9a-zA-Z]+\\|@[0-9]+\\$[0-9]+\\|[a-zA-Z]+\\([0-9]+\\|&\\)\\) *=")
+ (setq dest
+ (save-match-data
+ (org-table-convert-refs-to-rc (match-string 1))))
(org-table-add-rectangle-overlay
(match-beginning 1) (match-end 1) face2))))
(if (and (markerp pos) (marker-buffer pos))
(if (get-buffer-window (marker-buffer pos))
(select-window (get-buffer-window (marker-buffer pos)))
- (switch-to-buffer-other-window (get-buffer-window
+ (org-switch-to-buffer-other-window (get-buffer-window
(marker-buffer pos)))))
(goto-char pos)
(org-table-force-dataline)
(t
(cond
((not var) (error "No reference at point"))
+ ((setq e (assoc var org-table-formula-constants-local))
+ (message "Local Constant: $%s=%s in #+CONSTANTS line."
+ var (cdr e)))
((setq e (assoc var org-table-formula-constants))
(message "Constant: $%s=%s in `org-table-formula-constants'."
var (cdr e)))
((setq e (and (fboundp 'constants-get) (constants-get var)))
- (message "Constant: $%s=%s, retrieved from `constants.el'." var e))
+ (message "Constant: $%s=%s, from `constants.el'%s."
+ var e (format " (%s units)" constants-unit-system)))
(t (error "Undefined name $%s" var)))))
(goto-char pos)
- (when org-show-positions
+ (when (and org-show-positions
+ (not (memq this-command '(org-table-fedit-scroll
+ org-table-fedit-scroll-down))))
(push pos org-show-positions)
+ (push org-table-current-begin-pos org-show-positions)
(let ((min (apply 'min org-show-positions))
(max (apply 'max org-show-positions)))
- (when (or (not (pos-visible-in-window-p min))
- (not (pos-visible-in-window-p max)))
- (goto-char min)
- (set-window-start (selected-window) (point-at-bol))
- (goto-char pos))))
+ (goto-char min) (recenter 0)
+ (goto-char max)
+ (or (pos-visible-in-window-p max) (recenter -1))))
(select-window win))))
(defun org-table-force-dataline ()
((or p1 p2) (goto-char (or p1 p2)))
(t (error "No table dataline around here"))))))
-(defun org-table-edit-line-up ()
+(defun org-table-fedit-line-up ()
"Move cursor one line up in the window showing the table."
(interactive)
- (org-table-edit-move 'previous-line))
+ (org-table-fedit-move 'previous-line))
-(defun org-table-edit-line-down ()
+(defun org-table-fedit-line-down ()
"Move cursor one line down in the window showing the table."
(interactive)
- (org-table-edit-move 'next-line))
-
-(defun org-table-edit-backward-field ()
- "Move cursor one field backward in the window showing the table."
- (interactive)
- (org-table-edit-move 'org-table-previous-field))
-
-(defun org-table-edit-next-field ()
- "Move cursor one field forward in the window showing the table."
- (interactive)
- (org-table-edit-move 'org-table-next-field))
+ (org-table-fedit-move 'next-line))
-(defun org-table-edit-move (command)
+(defun org-table-fedit-move (command)
"Move the cursor in the window shoinw the table.
Use COMMAND to do the motion, repeat if necessary to end up in a data line."
(let ((org-table-allow-automatic-line-recalculation nil)
(move-marker pos (point))
(select-window win)))
-(defun org-table-edit-scroll (N)
+(defun org-table-fedit-scroll (N)
(interactive "p")
(let ((other-window-scroll-buffer (marker-buffer org-pos)))
(scroll-other-window N)))
-(defun org-table-edit-scroll-down (N)
+(defun org-table-fedit-scroll-down (N)
(interactive "p")
- (org-table-edit-scroll (- N)))
+ (org-table-fedit-scroll (- N)))
(defvar org-table-rectangle-overlays nil)
(mapc 'org-delete-overlay org-table-coordinate-overlays)
(setq org-table-coordinate-overlays nil)
(save-excursion
- (let ((id 0) (ih 0) hline eol str ic ov beg)
+ (let ((id 0) (ih 0) hline eol s1 s2 str ic ov beg)
(goto-char (org-table-begin))
(while (org-at-table-p)
(setq eol (point-at-eol))
(setq hline (looking-at org-table-hline-regexp))
(setq str (if hline (format "I*%-2d" (setq ih (1+ ih)))
(format "%4d" (setq id (1+ id)))))
- (org-overlay-before-string ov str 'org-formula 'evaporate)
+ (org-overlay-before-string ov str 'org-special-keyword 'evaporate)
(when hline
(setq ic 0)
- (while (re-search-forward "[+|]-+" eol t)
+ (while (re-search-forward "[+|]\\(-+\\)" eol t)
(setq beg (1+ (match-beginning 0))
- str (concat "$" (int-to-string (setq ic (1+ ic)))))
+ ic (1+ ic)
+ s1 (concat "$" (int-to-string ic))
+ s2 (org-number-to-letters ic)
+ str (if (eq org-table-use-standard-references t) s2 s1))
(setq ov (org-make-overlay beg (+ beg (length str))))
(push ov org-table-coordinate-overlays)
- (org-overlay-display ov str 'org-formula 'evaporate)))
+ (org-overlay-display ov str 'org-special-keyword 'evaporate)))
(beginning-of-line 2)))))
(defun org-table-toggle-coordinate-overlays ()
(defun orgtbl-error ()
"Error when there is no default binding for a table key."
(interactive)
- (error "This key is has no function outside tables"))
+ (error "This key has no function outside tables"))
(defun orgtbl-setup ()
"Setup orgtbl keymaps."
'("\C-c}" org-table-toggle-coordinate-overlays)
'("\C-c{" org-table-toggle-formula-debugger)
'("\C-m" org-table-next-row)
- (list (org-key 'S-return) 'org-table-copy-down)
+ '([(shift return)] org-table-copy-down)
'("\C-c\C-q" org-table-wrap-region)
'("\C-c?" org-table-field-info)
'("\C-c " org-table-blank-field)
elt key fun cmd)
(while (setq elt (pop bindings))
(setq nfunc (1+ nfunc))
- (setq key (car elt)
+ (setq key (org-key (car elt))
fun (nth 1 elt)
cmd (orgtbl-make-binding fun nfunc key))
- (define-key orgtbl-mode-map key cmd))
+ (org-defkey orgtbl-mode-map key cmd))
;; Special treatment needed for TAB and RET
- (define-key orgtbl-mode-map [(return)]
+ (org-defkey orgtbl-mode-map [(return)]
(orgtbl-make-binding 'orgtbl-ret 100 [(return)] "\C-m"))
- (define-key orgtbl-mode-map "\C-m"
+ (org-defkey orgtbl-mode-map "\C-m"
(orgtbl-make-binding 'orgtbl-ret 101 "\C-m" [(return)]))
- (define-key orgtbl-mode-map [(tab)]
+ (org-defkey orgtbl-mode-map [(tab)]
(orgtbl-make-binding 'orgtbl-tab 102 [(tab)] "\C-i"))
- (define-key orgtbl-mode-map "\C-i"
+ (org-defkey orgtbl-mode-map "\C-i"
(orgtbl-make-binding 'orgtbl-tab 103 "\C-i" [(tab)]))
- (define-key orgtbl-mode-map [(shift tab)]
+ (org-defkey orgtbl-mode-map [(shift tab)]
(orgtbl-make-binding 'org-table-previous-field 104
[(shift tab)] [(tab)] "\C-i"))
- (define-key orgtbl-mode-map "\M-\C-m"
+ (org-defkey orgtbl-mode-map "\M-\C-m"
(orgtbl-make-binding 'org-table-wrap-region 105
"\M-\C-m" [(meta return)]))
- (define-key orgtbl-mode-map [(meta return)]
+ (org-defkey orgtbl-mode-map [(meta return)]
(orgtbl-make-binding 'org-table-wrap-region 106
[(meta return)] "\M-\C-m"))
- (define-key orgtbl-mode-map "\C-c\C-c" 'orgtbl-ctrl-c-ctrl-c)
+ (org-defkey orgtbl-mode-map "\C-c\C-c" 'orgtbl-ctrl-c-ctrl-c)
(when orgtbl-optimized
;; If the user wants maximum table support, we need to hijack
;; some standard editing functions
'self-insert-command 'orgtbl-self-insert-command
'delete-char 'org-delete-char
'delete-backward-char 'org-delete-backward-char)
- (define-key orgtbl-mode-map "|" 'org-force-self-insert))
+ (org-defkey orgtbl-mode-map "|" 'org-force-self-insert))
(easy-menu-define orgtbl-mode-menu orgtbl-mode-map "OrgTbl menu"
'("OrgTbl"
["Align" org-ctrl-c-ctrl-c :active (org-at-table-p) :keys "C-c C-c"]
["Move Row Down" org-metadown :active (org-at-table-p) :keys "M-<down>"]
["Delete Row" org-shiftmetaup :active (org-at-table-p) :keys "M-S-<up>"]
["Insert Row" org-shiftmetadown :active (org-at-table-p) :keys "M-S-<down>"]
- ["Sort lines in region" org-table-sort-lines (org-at-table-p) :keys "C-c ^"]
+ ["Sort lines in region" org-table-sort-lines :active (org-at-table-p) :keys "C-c ^"]
"--"
["Insert Hline" org-table-insert-hline :active (org-at-table-p) :keys "C-c -"])
("Rectangle"
(defvar orgtbl-exp-regexp "^\\([-+]?[0-9][0-9.]*\\)[eE]\\([-+]?[0-9]+\\)$"
"Regula expression matching exponentials as produced by calc.")
-(defvar org-table-clean-did-remove-column-1 nil)
+(defvar org-table-clean-did-remove-column nil)
+
+(defun orgtbl-export (table target)
+ (let ((func (intern (concat "orgtbl-to-" (symbol-name target))))
+ (lines (org-split-string table "[ \t]*\n[ \t]*"))
+ org-table-last-alignment org-table-last-column-widths
+ maxcol column)
+ (if (not (fboundp func))
+ (error "Cannot export orgtbl table to %s" target))
+ (setq lines (org-table-clean-before-export lines))
+ (setq table
+ (mapcar
+ (lambda (x)
+ (if (string-match org-table-hline-regexp x)
+ 'hline
+ (org-split-string (org-trim x) "\\s-*|\\s-*")))
+ lines))
+ (setq maxcol (apply 'max (mapcar (lambda (x) (if (listp x) (length x) 0))
+ table)))
+ (loop for i from (1- maxcol) downto 0 do
+ (setq column (mapcar (lambda (x) (if (listp x) (nth i x) nil)) table))
+ (setq column (delq nil column))
+ (push (apply 'max (mapcar 'string-width column)) org-table-last-column-widths)
+ (push (> (/ (apply '+ (mapcar (lambda (x) (if (string-match org-table-number-regexp x) 1 0)) column)) maxcol) org-table-number-fraction) org-table-last-alignment))
+ (funcall func table nil)))
(defun orgtbl-send-table (&optional maybe)
"Send a tranformed version of this table to the receiver position.
(org-table-begin) (org-table-end)))
(lines (nthcdr (or skip 0) (org-split-string txt "[ \t]*\n[ \t]*")))
(lines (org-table-clean-before-export lines))
- (i0 (if org-table-clean-did-remove-column-1 2 1))
+ (i0 (if org-table-clean-did-remove-column 2 1))
(table (mapcar
(lambda (x)
(if (string-match org-table-hline-regexp x)
%s for the original field value. For example, to wrap
everything in dollars, you could use :fmt \"$%s$\".
This may also be a property list with column numbers and
- formats. for example :fmt (2 \"$%s$\" 4 \"%s%%\")
+ formats. For example :fmt (2 \"$%s$\" 4 \"%s%%\")
:hlstart :hlend :hlsep :hlfmt :hfmt
Same as above, specific for the header lines in the table.
:fmt A format to be used to wrap the field, should contain %s for the
original field value. For example, to wrap everything in dollars,
use :fmt \"$%s$\". This may also be a property list with column
- numbers and formats. for example :fmt (2 \"$%s$\" 4 \"%s%%\")
+ numbers and formats. For example :fmt (2 \"$%s$\" 4 \"%s%%\")
:efmt Format for transforming numbers with exponentials. The format
should have %s twice for inserting mantissa and exponent, for
%s for the original field value. For example, to wrap
everything in @kbd{}, you could use :fmt \"@kbd{%s}\".
This may also be a property list with column numbers and
- formats. for example :fmt (2 \"@kbd{%s}\" 4 \"@code{%s}\").
+ formats. For example :fmt (2 \"@kbd{%s}\" 4 \"@code{%s}\").
-:cf \"f1 f2..\" The column fractions for the table. Bye default these
+:cf \"f1 f2..\" The column fractions for the table. By default these
are computed automatically from the width of the columns
under org-mode.
(defun org-link-expand-abbrev (link)
"Apply replacements as defined in `org-link-abbrev-alist."
- (if (string-match "^\\([a-zA-Z]+\\)\\(::?\\(.*\\)\\)?$" link)
+ (if (string-match "^\\([a-zA-Z][-_a-zA-Z0-9]*\\)\\(::?\\(.*\\)\\)?$" link)
(let* ((key (match-string 1 link))
(as (or (assoc key org-link-abbrev-alist-local)
(assoc key org-link-abbrev-alist)))
(defvar org-store-link-plist nil
"Plist with info about the most recently link created with `org-store-link'.")
+(defvar org-link-protocols nil
+ "Link protocols added to Org-mode using `org-add-link-type'.")
+
+(defvar org-store-link-functions nil
+ "List of functions that are called to create and store a link.
+Each function will be called in turn until one returns a non-nil
+value. Each function should check if it is responsible for creating
+this link (for example by looking at the major mode).
+If not, it must exit and return nil.
+If yes, it should return a non-nil value after a calling
+`org-store-link-props' with a list of properties and values.
+Special properties are:
+
+:type The link prefix. like \"http\". This must be given.
+:link The link, like \"http://www.astro.uva.nl/~dominik\".
+ This is obligatory as well.
+:description Optional default description for the second pair
+ of brackets in an Org-mode link. The user can still change
+ this when inserting this link into an Org-mode buffer.
+
+In addition to these, any additional properties can be specified
+and then used in remember templates.")
+
+(defun org-add-link-type (type &optional follow publish)
+ "Add TYPE to the list of `org-link-types'.
+Re-compute all regular expressions depending on `org-link-types'
+FOLLOW and PUBLISH are two functions. Both take the link path as
+an argument.
+FOLLOW should do whatever is necessary to follow the link, for example
+to find a file or display a mail message.
+
+PUBLISH takes the path and retuns the string that should be used when
+this document is published. FIMXE: This is actually not yet implemented."
+ (add-to-list 'org-link-types type t)
+ (org-make-link-regexps)
+ (add-to-list 'org-link-protocols
+ (list type follow publish)))
+
+(defun org-add-agenda-custom-command (entry)
+ "Replace or add a command in `org-agenda-custom-commands'.
+This is mostly for hacking and trying a new command - once the command
+works you probably want to add it to `org-agenda-custom-commands' for good."
+ (let ((ass (assoc (car entry) org-agenda-custom-commands)))
+ (if ass
+ (setcdr ass (cdr entry))
+ (push entry org-agenda-custom-commands))))
+
;;;###autoload
(defun org-store-link (arg)
"\\<org-mode-map>Store an org-link to the current location.
-This link can later be inserted into an org-buffer with
-\\[org-insert-link].
+This link is added to `org-stored-links' and can later be inserted
+into an org-buffer with \\[org-insert-link].
+
For some link types, a prefix arg is interpreted:
For links to usenet articles, arg negates `org-usenet-links-prefer-google'.
For file links, arg negates `org-context-in-file-links'."
(interactive "P")
+ (require 'org-irc)
(setq org-store-link-plist nil) ; reset
(let (link cpltxt desc description search txt)
(cond
+ ((run-hook-with-args-until-success 'org-store-link-functions)
+ (setq link (plist-get org-store-link-plist :link)
+ desc (or (plist-get org-store-link-plist :description) link)))
+
((eq major-mode 'bbdb-mode)
(let ((name (bbdb-record-name (bbdb-current-record)))
- (company (bbdb-record-company (bbdb-current-record))))
+ (company (bbdb-record-getprop (bbdb-current-record) 'company)))
(setq cpltxt (concat "bbdb:" (or name company))
link (org-make-link cpltxt))
(org-store-link-props :type "bbdb" :name name :company company)))
(if (fboundp 'elmo-message-entity)
(elmo-message-entity
wl-summary-buffer-elmo-folder msgnum)
- (elmo-msgdb-overview-get-entity
- msgnum (wl-summary-buffer-msgdb))))
+ (elmo-msgdb-overview-get-entity
+ msgnum (wl-summary-buffer-msgdb))))
(from (wl-summary-line-from))
(to (car (elmo-message-entity-field wl-message-entity 'to)))
(subject (let (wl-thr-indent-string wl-parent-message-entity)
(setq link (org-make-link "mhe:" (org-mhe-get-message-real-folder) "#"
(org-remove-angle-brackets message-id)))))
- ((eq major-mode 'rmail-mode)
- (save-excursion
+ ((or (eq major-mode 'rmail-mode)
+ (eq major-mode 'rmail-summary-mode))
+ (save-window-excursion
(save-restriction
+ (when (eq major-mode 'rmail-summary-mode)
+ (rmail-show-message rmail-current-message))
(rmail-narrow-to-non-pruned-header)
(let ((folder buffer-file-name)
(message-id (mail-fetch-field "message-id"))
:subject subject :message-id message-id)
(setq message-id (org-remove-angle-brackets message-id))
(setq cpltxt (org-email-link-description))
- (setq link (org-make-link "rmail:" folder "#" message-id))))))
+ (setq link (org-make-link "rmail:" folder "#" message-id)))
+ (rmail-show-message rmail-current-message))))
((eq major-mode 'gnus-group-mode)
(let ((group (cond ((fboundp 'gnus-group-group-name) ; depending on Gnus
(setq cpltxt (substring cpltxt 0 -2)))
(setq link (org-make-link cpltxt)))
- (buffer-file-name
+ ((buffer-file-name (buffer-base-buffer))
;; Just link to this file here.
(setq cpltxt (concat "file:"
- (abbreviate-file-name buffer-file-name)))
+ (abbreviate-file-name
+ (buffer-file-name (buffer-base-buffer)))))
;; Add a context string
(when (org-xor org-context-in-file-links arg)
(setq txt (if (org-region-active-p)
(if (and (interactive-p) link)
(progn
(setq org-stored-links
- (cons (list cpltxt link desc) org-stored-links))
- (message "Stored: %s" (or cpltxt link)))
- (org-make-link-string link desc))))
+ (cons (list link desc) org-stored-links))
+ (message "Stored: %s" (or desc link)))
+ (and link (org-make-link-string link desc)))))
(defun org-store-link-props (&rest plist)
"Store link properties, extract names and addresses."
;; We are using a headline, clean up garbage in there.
(if (string-match org-todo-regexp s)
(setq s (replace-match "" t t s)))
- (if (string-match ":[a-zA-Z_@0-9:]+:[ \t]*$" s)
+ (if (string-match (org-re ":[[:alnum:]_@:]+:[ \t]*$") s)
(setq s (replace-match "" t t s)))
(setq s (org-trim s))
(if (string-match (concat "^\\(" org-quote-string "\\|"
(mapconcat 'identity (org-split-string s "[ \t]+") " ")))
(defun org-make-link (&rest strings)
- "Concatenate STRINGS, format resulting string with `org-link-format'."
+ "Concatenate STRINGS."
(apply 'concat strings))
(defun org-make-link-string (link &optional description)
"Make a link with brackets, consisting of LINK and DESCRIPTION."
+ (unless (string-match "\\S-" link)
+ (error "Empty link"))
(when (stringp description)
;; Remove brackets from the description, they are fatal.
- (while (string-match "\\[\\|\\]" description)
- (setq description (replace-match "" t t description))))
+ (while (string-match "\\[" description)
+ (setq description (replace-match "{" t t description)))
+ (while (string-match "\\]" description)
+ (setq description (replace-match "}" t t description))))
(when (equal (org-link-escape link) description)
;; No description needed, it is identical
(setq description nil))
(if description (concat "[" description "]") "")
"]"))
-(defconst org-link-escape-chars '(("[" . "%5B") ("]" . "%5D") (" " . "%20"))
- "Association list of escapes for some characters problematic in links.")
+(defconst org-link-escape-chars
+ '((?\ . "%20")
+ (?\[ . "%5B")
+ (?\] . "%5D")
+ (?\340 . "%E0") ; `a
+ (?\342 . "%E2") ; ^a
+ (?\347 . "%E7") ; ,c
+ (?\350 . "%E8") ; `e
+ (?\351 . "%E9") ; 'e
+ (?\352 . "%EA") ; ^e
+ (?\356 . "%EE") ; ^i
+ (?\364 . "%F4") ; ^o
+ (?\371 . "%F9") ; `u
+ (?\373 . "%FB") ; ^u
+ (?\; . "%3B")
+ (?? . "%3F")
+ (?= . "%3D")
+ (?+ . "%2B")
+ )
+ "Association list of escapes for some characters problematic in links.
+This is the list that is used for internal purposes.")
+
+(defconst org-link-escape-chars-browser
+ '((?\ . "%20")) ; 32 for the SPC char
+ "Association list of escapes for some characters problematic in links.
+This is the list that is used before handing over to the browser.")
-(defun org-link-escape (text)
+(defun org-link-escape (text &optional table)
"Escape charaters in TEXT that are problematic for links."
+ (setq table (or table org-link-escape-chars))
(when text
- (let ((re (mapconcat (lambda (x) (regexp-quote (car x)))
- org-link-escape-chars "\\|")))
+ (let ((re (mapconcat (lambda (x) (regexp-quote
+ (char-to-string (car x))))
+ table "\\|")))
(while (string-match re text)
(setq text
(replace-match
- (cdr (assoc (match-string 0 text) org-link-escape-chars))
+ (cdr (assoc (string-to-char (match-string 0 text))
+ table))
t t text)))
text)))
-(defun org-link-unescape (text)
+(defun org-link-unescape (text &optional table)
"Reverse the action of `org-link-escape'."
+ (setq table (or table org-link-escape-chars))
(when text
(let ((re (mapconcat (lambda (x) (regexp-quote (cdr x)))
- org-link-escape-chars "\\|")))
+ table "\\|")))
(while (string-match re text)
(setq text
(replace-match
- (car (rassoc (match-string 0 text) org-link-escape-chars))
+ (char-to-string (car (rassoc (match-string 0 text) table)))
t t text)))
text)))
(setq s (replace-match "%40" t t s)))
s)
+;;;###autoload
+(defun org-insert-link-global ()
+ "Insert a link like Org-mode does.
+This command can be called in any mode to insert a link in Org-mode syntax."
+ (interactive)
+ (org-run-like-in-org-mode 'org-insert-link))
+
(defun org-insert-link (&optional complete-file)
"Insert a link. At the prompt, enter the link.
With three \\[universal-argument] prefixes, negate the meaning of
`org-keep-stored-link-after-insertion'."
(interactive "P")
- (let ((region (if (org-region-active-p)
- (prog1 (buffer-substring (region-beginning) (region-end))
- (delete-region (region-beginning) (region-end)))))
- tmphist ; byte-compile incorrectly complains about this
- link desc entry remove file)
+ (let* ((wcf (current-window-configuration))
+ (region (if (org-region-active-p)
+ (buffer-substring (region-beginning) (region-end))))
+ (remove (and region (list (region-beginning) (region-end))))
+ (desc region)
+ tmphist ; byte-compile incorrectly complains about this
+ link entry file)
(cond
((org-in-regexp org-bracket-link-regexp 1)
;; We do have a link at point, and we are going to edit it.
(t (setq link (org-make-link "file:" file))))))
(t
;; Read link, with completion for stored links.
- ;; Fake a link history
+ (with-output-to-temp-buffer "*Org Links*"
+ (princ "Insert a link. Use TAB to complete valid link prefixes.\n")
+ (when org-stored-links
+ (princ "\nStored links are available with <up>/<down> or M-p/n (most recent with RET):\n\n")
+ (princ (mapconcat
+ (lambda (x)
+ (if (nth 1 x) (concat (car x) " (" (nth 1 x) ")") (car x)))
+ (reverse org-stored-links) "\n"))))
+ (let ((cw (selected-window)))
+ (select-window (get-buffer-window "*Org Links*"))
+ (shrink-window-if-larger-than-buffer)
+ (setq truncate-lines t)
+ (select-window cw))
+ ;; Fake a link history, containing the stored links.
(setq tmphist (append (mapcar 'car org-stored-links)
org-insert-link-history))
- (setq link (org-completing-read
- "Link: " org-stored-links nil nil nil
- 'tmphist
- (or (car (car org-stored-links)))))
+ (unwind-protect
+ (setq link (org-completing-read
+ "Link: "
+ (append
+ (mapcar (lambda (x) (list (concat (car x) ":")))
+ (append org-link-abbrev-alist-local org-link-abbrev-alist))
+ (mapcar (lambda (x) (list (concat x ":")))
+ org-link-types))
+ nil nil nil
+ 'tmphist
+ (or (car (car org-stored-links)))))
+ (set-window-configuration wcf)
+ (kill-buffer "*Org Links*"))
(setq entry (assoc link org-stored-links))
(or entry (push link org-insert-link-history))
(if (funcall (if (equal complete-file '(64)) 'not 'identity)
(not org-keep-stored-link-after-insertion))
(setq org-stored-links (delq (assoc link org-stored-links)
org-stored-links)))
- (setq link (if entry (nth 1 entry) link)
- desc (or region desc (nth 2 entry)))))
+ (setq desc (or desc (nth 1 entry)))))
(if (string-match org-plain-link-re link)
;; URL-like link, normalize the use of angular brackets.
;; Check if we can/should use a relative path. If yes, simplify the link
(when (string-match "\\<file:\\(.*\\)" link)
(let* ((path (match-string 1 link))
+ (origpath path)
(case-fold-search nil))
(cond
((eq org-link-file-path-type 'absolute)
;; We are linking a file with relative path name.
(setq path (substring (expand-file-name path)
(match-end 0)))))))
- (setq link (concat "file:" path))))
+ (setq link (concat "file:" path))
+ (if (equal desc origpath)
+ (setq desc path))))
(setq desc (read-string "Description: " desc))
(unless (string-match "\\S-" desc) (setq desc nil))
(defun org-completing-read (&rest args)
(let ((minibuffer-local-completion-map
(copy-keymap minibuffer-local-completion-map)))
- (define-key minibuffer-local-completion-map " " 'self-insert-command)
+ (org-defkey minibuffer-local-completion-map " " 'self-insert-command)
(apply 'completing-read args)))
;;; Opening/following a link
(defvar org-open-link-marker (make-marker)
"Marker pointing to the location where `org-open-at-point; was called.")
+;;;###autoload
+(defun org-open-at-point-global ()
+ "Follow a link like Org-mode does.
+This command can be called in any mode to follow a link that has
+Org-mode syntax."
+ (interactive)
+ (org-run-like-in-org-mode 'org-open-at-point))
+
(defun org-open-at-point (&optional in-emacs)
"Open link at or after point.
If there is no link at point, this function will search forward up to
Normally, files will be opened by an appropriate application. If the
optional argument IN-EMACS is non-nil, Emacs will visit the file."
(interactive "P")
+ (require 'org-irc)
(move-marker org-open-link-marker (point))
(setq org-window-config-before-follow-link (current-window-configuration))
(org-remove-occur-highlights nil nil t)
(org-in-regexp org-plain-link-re))
(setq type (match-string 1) path (match-string 2))
(throw 'match t)))
+ (when (org-in-regexp "\\<\\([^><\n]+\\)\\>")
+ (setq type "tree-match"
+ path (match-string 1))
+ (throw 'match t))
(save-excursion
- (when (org-in-regexp "\\(:[A-Za-z_@0-9:]+\\):[ \t\r\n]")
+ (when (org-in-regexp (org-re "\\(:[[:alnum:]_@:]+\\):[ \t]*$"))
(setq type "tags"
path (match-string 1))
(while (string-match ":" path)
(cond
+ ((assoc type org-link-protocols)
+ (funcall (nth 1 (assoc type org-link-protocols)) path))
+
((equal type "mailto")
(let ((cmd (car org-link-mailto-program))
(args (cdr org-link-mailto-program)) args1
(apply cmd (nreverse args1))))
((member type '("http" "https" "ftp" "news"))
+ (browse-url (concat type ":" (org-link-escape
+ path org-link-escape-chars-browser))))
+
+ ((member type '("message"))
(browse-url (concat type ":" path)))
((string= type "tags")
(switch-to-buffer-other-window
(org-get-buffer-for-internal-link (current-buffer)))
(org-mark-ring-push))
- (org-link-search
- path
- (cond ((equal in-emacs '(4)) 'occur)
- ((equal in-emacs '(16)) 'org-occur)
- (t nil))
- pos))
+ (let ((cmd `(org-link-search
+ ,path
+ ,(cond ((equal in-emacs '(4)) 'occur)
+ ((equal in-emacs '(16)) 'org-occur)
+ (t nil))
+ ,pos)))
+ (condition-case nil (eval cmd)
+ (error (progn (widen) (eval cmd))))))
+
+ ((string= type "tree-match")
+ (org-occur (concat "\\[" (regexp-quote path) "\\]")))
((string= type "file")
(if (string-match "::\\([0-9]+\\)\\'" path)
(if (string-match "::\\(.+\\)\\'" path)
(setq search (match-string 1 path)
path (substring path 0 (match-beginning 0)))))
- (org-open-file path in-emacs line search))
+ (if (string-match "[*?{]" (file-name-nondirectory path))
+ (dired path)
+ (org-open-file path in-emacs line search)))
((string= type "news")
(org-follow-gnus-link path))
((string= type "shell")
(let ((cmd path))
- ;; FIXME: the following is only for backward compatibility
- (while (string-match "@{" cmd) (setq cmd (replace-match "<" t t cmd)))
- (while (string-match "@}" cmd) (setq cmd (replace-match ">" t t cmd)))
(if (or (not org-confirm-shell-link-function)
(funcall org-confirm-shell-link-function
(format "Execute \"%s\" in shell? "
(funcall org-confirm-elisp-link-function
(format "Execute \"%s\" as elisp? "
(org-add-props cmd nil
- 'face 'org-warning))))
- (message "%s => %s" cmd (eval (read cmd)))
+ 'face 'org-warning))))
+ (message "%s => %s" cmd (eval (read cmd)))
(error "Abort"))))
(t
(browse-url-at-point)))))
- (move-marker org-open-link-marker nil))
-
+ (move-marker org-open-link-marker nil)
+ (run-hook-with-args 'org-follow-link-hook))
;;; File search
in all files. If AVOID-POS is given, ignore matches near that position."
(let ((case-fold-search t)
(s0 (mapconcat 'identity (org-split-string s "[ \t\r\n]+") " "))
+ (markers (concat "\\(?:" (mapconcat (lambda (x) (regexp-quote (car x)))
+ (append '(("") (" ") ("\t") ("\n"))
+ org-emphasis-alist)
+ "\\|") "\\)"))
(pos (point))
(pre "") (post "")
words re0 re1 re2 re3 re4 re5 re2a reall)
;; (grep (concat "grep -n -e '" (match-string 1 s) "' *")))
(t (org-do-occur (match-string 1 s)))))
(t
- ;; A normal search string
+ ;; A normal search strings
(when (equal (string-to-char s) ?*)
;; Anchor on headlines, post may include tags.
- (setq pre "^\\*+[ \t]*\\(?:\\sw+\\)?[ \t]*"
- post "[ \t]*\\(?:[ \t]+:[a-zA-Z_@0-9:+]:[ \t]*\\)?$"
+ (setq pre "^\\*+[ \t]+\\(?:\\sw+\\)?[ \t]*"
+ post (org-re "[ \t]*\\(?:[ \t]+:[[:alnum:]_@:+]:[ \t]*\\)?$")
s (substring s 1)))
(remove-text-properties
0 (length s)
;; Make a series of regular expressions to find a match
(setq words (org-split-string s "[ \n\r\t]+")
re0 (concat "\\(<<" (regexp-quote s0) ">>\\)")
- re2 (concat "[ \t\r\n]\\(" (mapconcat 'downcase words "[ \t]+") "\\)[ \t\r\n]")
+ re2 (concat markers "\\(" (mapconcat 'downcase words "[ \t]+")
+ "\\)" markers)
re2a (concat "[ \t\r\n]\\(" (mapconcat 'downcase words "[ \t\r\n]+") "\\)[ \t\r\n]")
re4 (concat "[^a-zA-Z_]\\(" (mapconcat 'downcase words "[^a-zA-Z_\r\n]+") "\\)[^a-zA-Z_]")
re1 (concat pre re2 post)
(let ((m org-open-link-marker))
(catch 'exit
(while (apply 're-search-forward args)
- (goto-char (match-end group))
- (if (and (or (not (eq (marker-buffer m) (current-buffer)))
- (> (match-beginning 0) (marker-position m))
- (< (match-end 0) (marker-position m)))
- (save-match-data
- (or (not (org-in-regexp org-bracket-link-analytic-regexp 1))
- (not (match-end 4)) ; no description
- (and (<= (match-beginning 4) (point))
- (>= (match-end 4) (point))))))
- (throw 'exit (point)))))))
+ (unless (get-text-property (match-end group) 'intangible) ; Emacs 21
+ (goto-char (match-end group))
+ (if (and (or (not (eq (marker-buffer m) (current-buffer)))
+ (> (match-beginning 0) (marker-position m))
+ (< (match-end 0) (marker-position m)))
+ (save-match-data
+ (or (not (org-in-regexp
+ org-bracket-link-analytic-regexp 1))
+ (not (match-end 4)) ; no description
+ (and (<= (match-beginning 4) (point))
+ (>= (match-end 4) (point))))))
+ (throw 'exit (point))))))))
(defun org-get-buffer-for-internal-link (buffer)
"Return a buffer to be used for displaying the link target of internal links."
(setq beg (match-end 0))
(if (re-search-forward "^[ \t]*[0-9]+" nil t)
(setq end (1- (match-beginning 0)))))
- (and beg end (let ((buffer-read-only)) (delete-region beg end)))
+ (and beg end (let ((inhibit-read-only t)) (delete-region beg end)))
(goto-char (point-min))
(select-window cwin))))
(move-marker (car org-mark-ring)
(or pos (point))
(or buffer (current-buffer)))
- (message
+ (message "%s"
(substitute-command-keys
"Position saved to mark ring, go back with \\[org-mark-ring-goto].")))
(if (match-string 2 name) ; If there isn't a node, choose "Top"
(Info-find-node (match-string 1 name) (match-string 2 name))
(Info-find-node (match-string 1 name) "Top")))
- (message (concat "Could not open: " name))))
+ (message "Could not open: %s" name)))
(defun org-follow-gnus-link (&optional group article)
"Follow a Gnus link to GROUP and ARTICLE."
(funcall (cdr (assq 'gnus org-link-frame-setup)))
(if gnus-other-frame-object (select-frame gnus-other-frame-object))
(cond ((and group article)
- (gnus-group-read-group 0 nil group)
+ (gnus-group-read-group 1 nil group)
(gnus-summary-goto-article (string-to-number article) nil t))
(group (gnus-group-jump-to-group group))))
(string= mh-index-folder (substring folder 0 end-index)))
(if (equal major-mode 'mh-show-mode)
(save-window-excursion
- (when (buffer-live-p (get-buffer folder))
- (progn
- (pop-to-buffer folder)
- (org-mhe-get-message-folder-from-index)
- )
- ))
+ (let (pop-up-frames)
+ (when (buffer-live-p (get-buffer folder))
+ (progn
+ (pop-to-buffer folder)
+ (org-mhe-get-message-folder-from-index)
+ )
+ )))
(org-mhe-get-message-folder-from-index)
)
folder
(save-excursion
(mh-index-previous-folder)
(re-search-forward "^\\(+.*\\)$" nil t)
- (message (match-string 1))))
+ (message "%s" (match-string 1))))
(defun org-mhe-get-message-folder ()
"Return the name of the current message folder. Be careful if you
(mh-show-buffer-message-number))))
(defun org-mhe-get-header (header)
- "Return a header of the message in folder mode. This will create a
-show buffer for the corresponding message. If you have a more clever
+ "Return a header of the message in folder mode. This will create a
+show buffer for the corresponding message. If you have a more clever
idea..."
(let* ((folder (org-mhe-get-message-folder))
(num (org-mhe-get-message-num))
(if (stringp command)
(setq cmd command)
(setq cmd 'emacs))))
- (if (and (not (eq cmd 'emacs)) ; Emacs has not problems with non-ex files
+ (if (and (not (eq cmd 'emacs)) ; Emacs has no problems with non-ex files
(not (file-exists-p file))
(not org-open-non-existing-files))
(error "No such file: %s" file))
(cond
((and (stringp cmd) (not (string-match "^\\s-*$" cmd)))
;; Remove quotes around the file name - we'll use shell-quote-argument.
- (if (string-match "['\"]%s['\"]" cmd)
- (setq cmd (replace-match "%s" t t cmd)))
- (setq cmd (format cmd (shell-quote-argument file)))
+ (while (string-match "['\"]%s['\"]" cmd)
+ (setq cmd (replace-match "%s" t t cmd)))
+ (while (string-match "%s" cmd)
+ (setq cmd (replace-match
+ (save-match-data (shell-quote-argument file))
+ t t cmd)))
(save-window-excursion
- (shell-command (concat cmd " &"))))
+ (start-process-shell-command cmd nil cmd)))
((or (stringp cmd)
(eq cmd 'emacs))
(funcall (cdr (assq 'file org-link-frame-setup)) file)
+ (widen)
(if line (goto-line line)
(if search (org-link-search search))))
((consp cmd)
org-file-apps-defaults-windowsnt)
(t org-file-apps-defaults-gnu)))
-(defun org-expand-file-name (path)
- "Replace special path abbreviations and expand the file name."
- (expand-file-name path))
-
(defvar ange-ftp-name-format) ; to silence the XEmacs compiler.
(defun org-file-remote-p (file)
"Test whether FILE specifies a location on a remote system.
(t nil)))
-;;;; Hooks for remember.el
+;;;; Hooks for remember.el, and refiling
+
+(defvar annotation) ; from remember.el, dynamically scoped in `remember-mode'
+(defvar initial) ; from remember.el, dynamically scoped in `remember-mode'
+
+;;;###autoload
+(defun org-remember-insinuate ()
+ "Setup remember.el for use wiht Org-mode."
+ (require 'remember)
+ (setq remember-annotation-functions '(org-remember-annotation))
+ (setq remember-handler-functions '(org-remember-handler))
+ (add-hook 'remember-mode-hook 'org-remember-apply-template))
;;;###autoload
(defun org-remember-annotation ()
(defconst org-remember-help
"Select a destination location for the note.
UP/DOWN=headline TAB=cycle visibility [Q]uit RET/<left>/<right>=Store
-RET at beg-of-buf -> Append to file as level 2 headline
RET on headline -> Store as sublevel entry to current headline
+RET at beg-of-buf -> Append to file as level 2 headline
<left>/<right> -> before/after current headline, same headings level")
+(defvar org-remember-previous-location nil)
+(defvar org-force-remember-template-char) ;; dynamically scoped
+
+;; Save the major mode of the buffer we called remember from
+(defvar org-select-template-temp-major-mode nil)
+
+;; Temporary store the buffer where remember was called from
+(defvar org-select-template-original-buffer nil)
+
+(defun org-select-remember-template (&optional use-char)
+ (when org-remember-templates
+ (let* ((pre-selected-templates
+ (mapcar
+ (lambda (tpl)
+ (let ((ctxt (nth 5 tpl))
+ (mode org-select-template-temp-major-mode)
+ (buf org-select-template-original-buffer))
+ (and (or (not ctxt) (eq ctxt t)
+ (and (listp ctxt) (memq mode ctxt))
+ (and (functionp ctxt)
+ (with-current-buffer buf
+ ;; Protect the user-defined function from error
+ (condition-case nil (funcall ctxt) (error nil)))))
+ tpl)))
+ org-remember-templates))
+ ;; If no template at this point, add the default templates:
+ (pre-selected-templates1
+ (if (not (delq nil pre-selected-templates))
+ (mapcar (lambda(x) (if (not (nth 5 x)) x))
+ org-remember-templates)
+ pre-selected-templates))
+ ;; Then unconditionnally add template for any contexts
+ (pre-selected-templates2
+ (append (mapcar (lambda(x) (if (eq (nth 5 x) t) x))
+ org-remember-templates)
+ (delq nil pre-selected-templates1)))
+ (templates (mapcar (lambda (x)
+ (if (stringp (car x))
+ (append (list (nth 1 x) (car x)) (cddr x))
+ (append (list (car x) "") (cdr x))))
+ (delq nil pre-selected-templates2)))
+ (char (or use-char
+ (cond
+ ((= (length templates) 1)
+ (caar templates))
+ ((and (boundp 'org-force-remember-template-char)
+ org-force-remember-template-char)
+ (if (stringp org-force-remember-template-char)
+ (string-to-char org-force-remember-template-char)
+ org-force-remember-template-char))
+ (t
+ (message "Select template: %s"
+ (mapconcat
+ (lambda (x)
+ (cond
+ ((not (string-match "\\S-" (nth 1 x)))
+ (format "[%c]" (car x)))
+ ((equal (downcase (car x))
+ (downcase (aref (nth 1 x) 0)))
+ (format "[%c]%s" (car x)
+ (substring (nth 1 x) 1)))
+ (t (format "[%c]%s" (car x) (nth 1 x)))))
+ templates " "))
+ (let ((inhibit-quit t) (char0 (read-char-exclusive)))
+ (when (equal char0 ?\C-g)
+ (jump-to-register remember-register)
+ (kill-buffer remember-buffer))
+ char0))))))
+ (cddr (assoc char templates)))))
+
+(defvar x-last-selected-text)
+(defvar x-last-selected-text-primary)
+
;;;###autoload
(defun org-remember-apply-template (&optional use-char skip-interactive)
"Initialize *remember* buffer with template, invoke `org-mode'.
This function should be placed into `remember-mode-hook' and in fact requires
-to be run from that hook to fucntion properly."
+to be run from that hook to function properly."
(if org-remember-templates
-
- (let* ((char (or use-char
- (if (= (length org-remember-templates) 1)
- (caar org-remember-templates)
- (message "Select template: %s"
- (mapconcat
- (lambda (x) (char-to-string (car x)))
- org-remember-templates " "))
- (read-char-exclusive))))
- (entry (cdr (assoc char org-remember-templates)))
+ (let* ((entry (org-select-remember-template use-char))
(tpl (car entry))
(plist-p (if org-store-link-plist t nil))
(file (if (and (nth 1 entry) (stringp (nth 1 entry))
(nth 1 entry)
org-default-notes-file))
(headline (nth 2 entry))
+ (v-c (or (and (eq window-system 'x)
+ (fboundp 'x-cut-buffer-or-selection-value)
+ (x-cut-buffer-or-selection-value))
+ (org-bound-and-true-p x-last-selected-text)
+ (org-bound-and-true-p x-last-selected-text-primary)
+ (and (> (length kill-ring) 0) (current-kill 0))))
(v-t (format-time-string (car org-time-stamp-formats) (org-current-time)))
(v-T (format-time-string (cdr org-time-stamp-formats) (org-current-time)))
(v-u (concat "[" (substring v-t 1 -1) "]"))
(v-U (concat "[" (substring v-T 1 -1) "]"))
- (v-i initial) ; defined in `remember-mode'
- (v-a (if (equal annotation "[[]]") "" annotation)) ; likewise
+ ;; `initial' and `annotation' are bound in `remember'
+ (v-i (if (boundp 'initial) initial))
+ (v-a (if (and (boundp 'annotation) annotation)
+ (if (equal annotation "[[]]") "" annotation)
+ ""))
+ (v-A (if (and v-a
+ (string-match "\\[\\(\\[.*?\\]\\)\\(\\[.*?\\]\\)?\\]" v-a))
+ (replace-match "[\\1[%^{Link description}]]" nil nil v-a)
+ v-a))
(v-n user-full-name)
(org-startup-folded nil)
- org-time-was-given x prompt char time)
+ org-time-was-given org-end-time-was-given x
+ prompt completions char time pos default histvar)
(setq org-store-link-plist
- (append (list :annotation v-a :initial v-i)))
- (unless tpl (setq tpl "") (message "No template") (ding))
+ (append (list :annotation v-a :initial v-i)
+ org-store-link-plist))
+ (unless tpl (setq tpl "") (message "No template") (ding) (sit-for 1))
(erase-buffer)
(insert (substitute-command-keys
(format
- "## `C-c C-c' to file interactively, `C-u C-c C-c' to file directly.
-## Target file \"%s\", headline \"%s\"
-## To switch templates, use `\\[org-remember]'.\n\n"
+"## Filing location: Select interactively, default, or last used:
+## %s to select file and header location interactively.
+## %s \"%s\" -> \"* %s\"
+## C-u C-u C-c C-c \"%s\" -> \"* %s\"
+## To switch templates, use `\\[org-remember]'. To abort use `C-c C-k'.\n\n"
+ (if org-remember-store-without-prompt " C-u C-c C-c" " C-c C-c")
+ (if org-remember-store-without-prompt " C-c C-c" " C-u C-c C-c")
(abbreviate-file-name (or file org-default-notes-file))
- (or headline ""))))
+ (or headline "")
+ (or (car org-remember-previous-location) "???")
+ (or (cdr org-remember-previous-location) "???"))))
(insert tpl) (goto-char (point-min))
;; Simple %-escapes
- (while (re-search-forward "%\\([tTuUai]\\)" nil t)
+ (while (re-search-forward "%\\([tTuUaiAc]\\)" nil t)
(when (and initial (equal (match-string 0) "%i"))
(save-match-data
(let* ((lead (buffer-substring
(replace-match
(or (eval (intern (concat "v-" (match-string 1)))) "")
t t))
+
+ ;; %[] Insert contents of a file.
+ (goto-char (point-min))
+ (while (re-search-forward "%\\[\\(.+\\)\\]" nil t)
+ (let ((start (match-beginning 0))
+ (end (match-end 0))
+ (filename (expand-file-name (match-string 1))))
+ (goto-char start)
+ (delete-region start end)
+ (condition-case error
+ (insert-file-contents filename)
+ (error (insert (format "%%![Couldn't insert %s: %s]"
+ filename error))))))
+ ;; %() embedded elisp
+ (goto-char (point-min))
+ (while (re-search-forward "%\\((.+)\\)" nil t)
+ (goto-char (match-beginning 0))
+ (let ((template-start (point)))
+ (forward-char 1)
+ (let ((result
+ (condition-case error
+ (eval (read (current-buffer)))
+ (error (format "%%![Error: %s]" error)))))
+ (delete-region template-start (point))
+ (insert result))))
+
;; From the property list
(when plist-p
(goto-char (point-min))
(while (re-search-forward "%\\(:[-a-zA-Z]+\\)" nil t)
- (and (setq x (plist-get org-store-link-plist
- (intern (match-string 1))))
+ (and (setq x (or (plist-get org-store-link-plist
+ (intern (match-string 1))) ""))
(replace-match x t t))))
+
;; Turn on org-mode in the remember buffer, set local variables
(org-mode)
- (org-set-local 'org-finish-function 'remember-buffer)
+ (org-set-local 'org-finish-function 'org-remember-finalize)
(if (and file (string-match "\\S-" file) (not (file-directory-p file)))
(org-set-local 'org-default-notes-file file))
(if (and headline (stringp headline) (string-match "\\S-" headline))
(org-set-local 'org-remember-default-headline headline))
;; Interactive template entries
(goto-char (point-min))
- (while (re-search-forward "%^\\({\\([^}]*\\)}\\)?\\([uUtT]\\)?" nil t)
+ (while (re-search-forward "%^\\({\\([^}]*\\)}\\)?\\([gGuUtT]\\)?" nil t)
(setq char (if (match-end 3) (match-string 3))
prompt (if (match-end 2) (match-string 2)))
(goto-char (match-beginning 0))
(replace-match "")
- (if char
- (progn
- (setq org-time-was-given (equal (upcase char) char))
- (setq time (org-read-date (equal (upcase char) "U") t nil
- prompt))
- (org-insert-time-stamp time org-time-was-given
- (member char '("u" "U"))))
- (insert (read-string
- (if prompt (concat prompt ": ") "Enter string")))))
+ (setq completions nil default nil)
+ (when prompt
+ (setq completions (org-split-string prompt "|")
+ prompt (pop completions)
+ default (car completions)
+ histvar (intern (concat
+ "org-remember-template-prompt-history::"
+ (or prompt "")))
+ completions (mapcar 'list completions)))
+ (cond
+ ((member char '("G" "g"))
+ (let* ((org-last-tags-completion-table
+ (org-global-tags-completion-table
+ (if (equal char "G") (org-agenda-files) (and file (list file)))))
+ (org-add-colon-after-tag-completion t)
+ (ins (completing-read
+ (if prompt (concat prompt ": ") "Tags: ")
+ 'org-tags-completion-function nil nil nil
+ 'org-tags-history)))
+ (setq ins (mapconcat 'identity
+ (org-split-string ins (org-re "[^[:alnum:]_@]+"))
+ ":"))
+ (when (string-match "\\S-" ins)
+ (or (equal (char-before) ?:) (insert ":"))
+ (insert ins)
+ (or (equal (char-after) ?:) (insert ":")))))
+ (char
+ (setq org-time-was-given (equal (upcase char) char))
+ (setq time (org-read-date (equal (upcase char) "U") t nil
+ prompt))
+ (org-insert-time-stamp time org-time-was-given
+ (member char '("u" "U"))
+ nil nil (list org-end-time-was-given)))
+ (t
+ (insert (org-completing-read
+ (concat (if prompt prompt "Enter string")
+ (if default (concat " [" default "]"))
+ ": ")
+ completions nil nil nil histvar default)))))
(goto-char (point-min))
(if (re-search-forward "%\\?" nil t)
(replace-match "")
(and (re-search-forward "^[^#\n]" nil t) (backward-char 1))))
(org-mode)
- (org-set-local 'org-finish-function 'remember-buffer)))
+ (org-set-local 'org-finish-function 'org-remember-finalize))
+ (when (save-excursion
+ (goto-char (point-min))
+ (re-search-forward "%!" nil t))
+ (replace-match "")
+ (add-hook 'post-command-hook 'org-remember-finish-immediately 'append)))
+
+(defun org-remember-finish-immediately ()
+ "File remember note immediately.
+This should be run in `post-command-hook' and will remove itself
+from that hook."
+ (remove-hook 'post-command-hook 'org-remember-finish-immediately)
+ (when org-finish-function
+ (funcall org-finish-function)))
+
+(defvar org-clock-marker) ; Defined below
+(defun org-remember-finalize ()
+ "Finalize the remember process."
+ (unless (fboundp 'remember-finalize)
+ (defalias 'remember-finalize 'remember-buffer))
+ (when (and org-clock-marker
+ (equal (marker-buffer org-clock-marker) (current-buffer)))
+ ;; FIXME: test this, this is w/o notetaking!
+ (let (org-log-note-clock-out) (org-clock-out)))
+ (when buffer-file-name
+ (save-buffer)
+ (setq buffer-file-name nil))
+ (remember-finalize))
;;;###autoload
-(defun org-remember ()
+(defun org-remember (&optional goto org-force-remember-template-char)
"Call `remember'. If this is already a remember buffer, re-apply template.
If there is an active region, make sure remember uses it as initial content
-of the remember buffer."
+of the remember buffer.
+
+When called interactively with a `C-u' prefix argument GOTO, don't remember
+anything, just go to the file/headline where the selected template usually
+stores its notes. With a double prefix arg `C-u C-u', go to the last
+note stored by remember.
+
+Lisp programs can set ORG-FORCE-REMEMBER-TEMPLATE-CHAR to a character
+associated with a template in `org-remember-templates'."
+ (interactive "P")
+ (cond
+ ((equal goto '(4)) (org-go-to-remember-target))
+ ((equal goto '(16)) (org-remember-goto-last-stored))
+ (t
+ ;; set temporary variables that will be needed in
+ ;; `org-select-remember-template'
+ (setq org-select-template-temp-major-mode major-mode)
+ (setq org-select-template-original-buffer (current-buffer))
+ (if (memq org-finish-function '(remember-buffer remember-finalize))
+ (progn
+ (when (< (length org-remember-templates) 2)
+ (error "No other template available"))
+ (erase-buffer)
+ (let ((annotation (plist-get org-store-link-plist :annotation))
+ (initial (plist-get org-store-link-plist :initial)))
+ (org-remember-apply-template))
+ (message "Press C-c C-c to remember data"))
+ (if (org-region-active-p)
+ (remember (buffer-substring (point) (mark)))
+ (call-interactively 'remember))))))
+
+(defun org-remember-goto-last-stored ()
+ "Go to the location where the last remember note was stored."
(interactive)
- (if (eq org-finish-function 'remember-buffer)
- (progn
- (when (< (length org-remember-templates) 2)
- (error "No other template available"))
- (erase-buffer)
- (let ((annotation (plist-get org-store-link-plist :annotation))
- (initial (plist-get org-store-link-plist :initial)))
- (org-remember-apply-template))
- (message "Press C-c C-c to remember data"))
- (if (org-region-active-p)
- (remember (buffer-substring (point) (mark)))
- (call-interactively 'remember))))
+ (bookmark-jump "org-remember-last-stored")
+ (message "This is the last note stored by remember"))
-;;;###autoload
-(defun org-remember-handler ()
+(defun org-go-to-remember-target (&optional template-key)
+ "Go to the target location of a remember template.
+The user is queried for the template."
+ (interactive)
+ (let* (org-select-template-temp-major-mode
+ (entry (org-select-remember-template template-key))
+ (file (nth 1 entry))
+ (heading (nth 2 entry))
+ visiting)
+ (unless (and file (stringp file) (string-match "\\S-" file))
+ (setq file org-default-notes-file))
+ (unless (and heading (stringp heading) (string-match "\\S-" heading))
+ (setq heading org-remember-default-headline))
+ (setq visiting (org-find-base-buffer-visiting file))
+ (if (not visiting) (find-file-noselect file))
+ (switch-to-buffer (or visiting (get-file-buffer file)))
+ (widen)
+ (goto-char (point-min))
+ (if (re-search-forward
+ (concat "^\\*+[ \t]+" (regexp-quote heading)
+ (org-re "\\([ \t]+:[[:alnum:]@_:]*\\)?[ \t]*$"))
+ nil t)
+ (goto-char (match-beginning 0))
+ (error "Target headline not found: %s" heading))))
+
+(defvar org-note-abort nil) ; dynamically scoped
+
+;;;###autoload
+(defun org-remember-handler ()
"Store stuff from remember.el into an org file.
First prompts for an org file. If the user just presses return, the value
of `org-default-notes-file' is used.
Key Cursor position Note gets inserted
-----------------------------------------------------------------------------
-RET buffer-start as level 2 heading at end of file
+RET buffer-start as level 1 heading at end of file
RET on headline as sublevel of the heading at cursor
RET no heading at cursor position, level taken from context.
Or use prefix arg to specify level manually.
So the fastest way to store the note is to press RET RET to append it to
the default file. This way your current train of thought is not
-interrupted, in accordance with the principles of remember.el. But with
-little extra effort, you can push it directly to the correct location.
+interrupted, in accordance with the principles of remember.el.
+You can also get the fast execution without prompting by using
+C-u C-c C-c to exit the remember buffer. See also the variable
+`org-remember-store-without-prompt'.
Before being stored away, the function ensures that the text has a
headline, i.e. a first line that starts with a \"*\". If not, a headline
(goto-char (point-min))
(while (looking-at "^[ \t]*\n\\|^##.*\n")
(replace-match ""))
+ (goto-char (point-max))
+ (beginning-of-line 1)
+ (while (looking-at "[ \t]*$\\|##.*")
+ (delete-region (1- (point)) (point-max))
+ (beginning-of-line 1))
(catch 'quit
+ (if org-note-abort (throw 'quit nil))
(let* ((txt (buffer-substring (point-min) (point-max)))
- (fastp current-prefix-arg)
- (file (if fastp org-default-notes-file (org-get-org-file)))
+ (fastp (org-xor (equal current-prefix-arg '(4))
+ org-remember-store-without-prompt))
+ (file (cond
+ (fastp org-default-notes-file)
+ ((and (eq org-remember-interactive-interface 'refile)
+ org-refile-targets)
+ org-default-notes-file)
+ ((not (and (equal current-prefix-arg '(16))
+ org-remember-previous-location))
+ (org-get-org-file))))
(heading org-remember-default-headline)
- (visiting (org-find-base-buffer-visiting file))
+ (visiting (and file (org-find-base-buffer-visiting file)))
(org-startup-folded nil)
(org-startup-align-all-tables nil)
(org-goto-start-pos 1)
- spos level indent reversed)
+ spos exitcmd level indent reversed)
+ (if (and (equal current-prefix-arg '(16)) org-remember-previous-location)
+ (setq file (car org-remember-previous-location)
+ heading (cdr org-remember-previous-location)
+ fastp t))
+ (setq current-prefix-arg nil)
+ (if (string-match "[ \t\n]+\\'" txt)
+ (setq txt (replace-match "" t t txt)))
;; Modify text so that it becomes a nice subtree which can be inserted
;; into an org tree.
(let* ((lines (split-string txt "\n"))
first)
(setq first (car lines) lines (cdr lines))
- (if (string-match "^\\*+" first)
+ (if (string-match "^\\*+ " first)
;; Is already a headline
(setq indent nil)
;; We need to add a headline: Use time and first buffer line
" (" (remember-buffer-desc) ")")
indent " "))
(if (and org-adapt-indentation indent)
- (setq lines (mapcar (lambda (x) (concat indent x)) lines)))
+ (setq lines (mapcar
+ (lambda (x)
+ (if (string-match "\\S-" x)
+ (concat indent x) x))
+ lines)))
(setq txt (concat first "\n"
(mapconcat 'identity lines "\n"))))
+ (if (string-match "\n[ \t]*\n[ \t\n]*\\'" txt)
+ (setq txt (replace-match "\n\n" t t txt))
+ (if (string-match "[ \t\n]*\\'" txt)
+ (setq txt (replace-match "\n" t t txt))))
+ ;; Put the modified text back into the remember buffer, for refile.
+ (erase-buffer)
+ (insert txt)
+ (goto-char (point-min))
+ (when (and (eq org-remember-interactive-interface 'refile)
+ (not fastp))
+ (org-refile nil (or visiting (find-file-noselect file)))
+ (throw 'quit t))
;; Find the file
(if (not visiting) (find-file-noselect file))
(with-current-buffer (or visiting (get-file-buffer file))
- (save-excursion (and (goto-char (point-min))
- (not (re-search-forward "^\\* " nil t))
- (insert "\n* Notes\n")))
- (setq reversed (org-notes-order-reversed-p))
+ (unless (org-mode-p)
+ (error "Target files for remember notes must be in Org-mode"))
(save-excursion
(save-restriction
(widen)
+ (and (goto-char (point-min))
+ (not (re-search-forward "^\\* " nil t))
+ (insert "\n* " (or heading "Notes") "\n"))
+ (setq reversed (org-notes-order-reversed-p))
;; Find the default location
(when (and heading (stringp heading) (string-match "\\S-" heading))
(goto-char (point-min))
(if (re-search-forward
(concat "^\\*+[ \t]+" (regexp-quote heading)
- "\\([ \t]+:[@a-zA-Z0-9_:]*\\)?[ \t]*$")
+ (org-re "\\([ \t]+:[[:alnum:]@_:]*\\)?[ \t]*$"))
nil t)
- (setq org-goto-start-pos (match-beginning 0))))
+ (setq org-goto-start-pos (match-beginning 0))
+ (when fastp
+ (goto-char (point-max))
+ (unless (bolp) (newline))
+ (insert "* " heading "\n")
+ (setq org-goto-start-pos (point-at-bol 0)))))
- ;; Ask the User for a location
- (setq spos (if fastp
- org-goto-start-pos
- (org-get-location (current-buffer) org-remember-help)))
+ ;; Ask the User for a location, using the appropriate interface
+ (cond
+ (fastp (setq spos org-goto-start-pos
+ exitcmd 'return))
+ ((eq org-remember-interactive-interface 'outline)
+ (setq spos (org-get-location (current-buffer)
+ org-remember-help)
+ exitcmd (cdr spos)
+ spos (car spos)))
+ ((eq org-remember-interactive-interface 'outline-path-completion)
+ (let ((org-refile-targets '((nil . (:maxlevel . 10))))
+ (org-refile-use-outline-path t))
+ (setq spos (org-refile-get-location "Heading: ")
+ exitcmd 'return
+ spos (nth 3 spos))))
+ (t (error "this should not hapen")))
(if (not spos) (throw 'quit nil)) ; return nil to show we did
- ; not handle this note
+ ; not handle this note
(goto-char spos)
- (cond ((and (bobp) (not reversed))
+ (cond ((org-on-heading-p t)
+ (org-back-to-heading t)
+ (setq level (funcall outline-level))
+ (cond
+ ((eq exitcmd 'return)
+ ;; sublevel of current
+ (setq org-remember-previous-location
+ (cons (abbreviate-file-name file)
+ (org-get-heading 'notags)))
+ (if reversed
+ (outline-next-heading)
+ (org-end-of-subtree t)
+ (if (not (bolp))
+ (if (looking-at "[ \t]*\n")
+ (beginning-of-line 2)
+ (end-of-line 1)
+ (insert "\n"))))
+ (bookmark-set "org-remember-last-stored")
+ (org-paste-subtree (org-get-valid-level level 1) txt))
+ ((eq exitcmd 'left)
+ ;; before current
+ (bookmark-set "org-remember-last-stored")
+ (org-paste-subtree level txt))
+ ((eq exitcmd 'right)
+ ;; after current
+ (org-end-of-subtree t)
+ (bookmark-set "org-remember-last-stored")
+ (org-paste-subtree level txt))
+ (t (error "This should not happen"))))
+
+ ((and (bobp) (not reversed))
;; Put it at the end, one level below level 1
(save-restriction
(widen)
(goto-char (point-max))
(if (not (bolp)) (newline))
- (org-paste-subtree (org-get-legal-level 1 1) txt)))
+ (bookmark-set "org-remember-last-stored")
+ (org-paste-subtree (org-get-valid-level 1 1) txt)))
+
((and (bobp) reversed)
;; Put it at the start, as level 1
(save-restriction
(widen)
(goto-char (point-min))
- (re-search-forward "^\\*" nil t)
+ (re-search-forward "^\\*+ " nil t)
(beginning-of-line 1)
+ (bookmark-set "org-remember-last-stored")
(org-paste-subtree 1 txt)))
- ((and (org-on-heading-p nil) (not current-prefix-arg))
- ;; Put it below this entry, at the beg/end of the subtree
- (org-back-to-heading t)
- (setq level (funcall outline-level))
- (if reversed
- (outline-end-of-heading)
- (org-end-of-subtree t))
- (if (not (bolp)) (newline))
- (beginning-of-line 1)
- (org-paste-subtree (org-get-legal-level level 1) txt))
(t
;; Put it right there, with automatic level determined by
;; org-paste-subtree or from prefix arg
- (org-paste-subtree current-prefix-arg txt)))
+ (bookmark-set "org-remember-last-stored")
+ (org-paste-subtree
+ (if (numberp current-prefix-arg) current-prefix-arg)
+ txt)))
(when remember-save-after-remembering
(save-buffer)
(if (not visiting) (kill-buffer (current-buffer)))))))))
+
t) ;; return t to indicate that we took care of this note.
(defun org-get-org-file ()
(throw 'exit (cdr entry))))
nil)))))
+;;; Refiling
+
+(defvar org-refile-target-table nil
+ "The list of refile targets, created by `org-refile'.")
+
+(defvar org-agenda-new-buffers nil
+ "Buffers created to visit agenda files.")
+
+(defun org-get-refile-targets (&optional default-buffer)
+ "Produce a table with refile targets."
+ (let ((entries (or org-refile-targets '((nil . (:level . 1)))))
+ targets txt re files f desc descre)
+ (with-current-buffer (or default-buffer (current-buffer))
+ (while (setq entry (pop entries))
+ (setq files (car entry) desc (cdr entry))
+ (cond
+ ((null files) (setq files (list (current-buffer))))
+ ((eq files 'org-agenda-files)
+ (setq files (org-agenda-files 'unrestricted)))
+ ((and (symbolp files) (fboundp files))
+ (setq files (funcall files)))
+ ((and (symbolp files) (boundp files))
+ (setq files (symbol-value files))))
+ (if (stringp files) (setq files (list files)))
+ (cond
+ ((eq (car desc) :tag)
+ (setq descre (concat "^\\*+[ \t]+.*?:" (regexp-quote (cdr desc)) ":")))
+ ((eq (car desc) :todo)
+ (setq descre (concat "^\\*+[ \t]+" (regexp-quote (cdr desc)) "[ \t]")))
+ ((eq (car desc) :regexp)
+ (setq descre (cdr desc)))
+ ((eq (car desc) :level)
+ (setq descre (concat "^\\*\\{" (number-to-string
+ (if org-odd-levels-only
+ (1- (* 2 (cdr desc)))
+ (cdr desc)))
+ "\\}[ \t]")))
+ ((eq (car desc) :maxlevel)
+ (setq descre (concat "^\\*\\{1," (number-to-string
+ (if org-odd-levels-only
+ (1- (* 2 (cdr desc)))
+ (cdr desc)))
+ "\\}[ \t]")))
+ (t (error "Bad refiling target description %s" desc)))
+ (while (setq f (pop files))
+ (save-excursion
+ (set-buffer (if (bufferp f) f (org-get-agenda-file-buffer f)))
+ (if (bufferp f) (setq f (buffer-file-name (buffer-base-buffer f))))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (while (re-search-forward descre nil t)
+ (goto-char (point-at-bol))
+ (when (looking-at org-complex-heading-regexp)
+ (setq txt (match-string 4)
+ re (concat "^" (regexp-quote
+ (buffer-substring (match-beginning 1)
+ (match-end 4)))))
+ (if (match-end 5) (setq re (concat re "[ \t]+"
+ (regexp-quote
+ (match-string 5)))))
+ (setq re (concat re "[ \t]*$"))
+ (when org-refile-use-outline-path
+ (setq txt (mapconcat 'identity
+ (append
+ (if (eq org-refile-use-outline-path 'file)
+ (list (file-name-nondirectory
+ (buffer-file-name (buffer-base-buffer))))
+ (if (eq org-refile-use-outline-path 'full-file-path)
+ (list (buffer-file-name (buffer-base-buffer)))))
+ (org-get-outline-path)
+ (list txt))
+ "/")))
+ (push (list txt f re (point)) targets))
+ (goto-char (point-at-eol))))))))
+ (nreverse targets))))
+
+(defun org-get-outline-path ()
+ "Return the outline path to the current entry, as a list."
+ (let (rtn)
+ (save-excursion
+ (while (org-up-heading-safe)
+ (when (looking-at org-complex-heading-regexp)
+ (push (org-match-string-no-properties 4) rtn)))
+ rtn)))
+
+(defvar org-refile-history nil
+ "History for refiling operations.")
+
+(defun org-refile (&optional goto default-buffer)
+ "Move the entry at point to another heading.
+The list of target headings is compiled using the information in
+`org-refile-targets', which see. This list is created upon first use, and
+you can update it by calling this command with a double prefix (`C-u C-u').
+FIXME: Can we find a better way of updating?
+
+At the target location, the entry is filed as a subitem of the target heading.
+Depending on `org-reverse-note-order', the new subitem will either be the
+first of the last subitem.
+
+With prefix arg GOTO, the command will only visit the target location,
+not actually move anything.
+With a double prefix `C-c C-c', go to the location where the last refiling
+operation has put the subtree.
+
+With a double prefix argument, the command can be used to jump to any
+heading in the current buffer."
+ (interactive "P")
+ (let* ((cbuf (current-buffer))
+ (filename (buffer-file-name (buffer-base-buffer cbuf)))
+ pos it nbuf file re level reversed)
+ (if (equal goto '(16))
+ (org-refile-goto-last-stored)
+ (when (setq it (org-refile-get-location
+ (if goto "Goto: " "Refile to: ") default-buffer))
+ (setq file (nth 1 it)
+ re (nth 2 it)
+ pos (nth 3 it))
+ (setq nbuf (or (find-buffer-visiting file)
+ (find-file-noselect file)))
+ (if goto
+ (progn
+ (switch-to-buffer nbuf)
+ (goto-char pos)
+ (org-show-context 'org-goto))
+ (org-copy-special)
+ (save-excursion
+ (set-buffer (setq nbuf (or (find-buffer-visiting file)
+ (find-file-noselect file))))
+ (setq reversed (org-notes-order-reversed-p))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char pos)
+ (looking-at outline-regexp)
+ (setq level (org-get-valid-level (funcall outline-level) 1))
+ (goto-char
+ (if reversed
+ (outline-next-heading)
+ (or (save-excursion (outline-get-next-sibling))
+ (org-end-of-subtree t t)
+ (point-max))))
+ (bookmark-set "org-refile-last-stored")
+ (org-paste-subtree level))))
+ (org-cut-special)
+ (message "Entry refiled to \"%s\"" (car it)))))))
+
+(defun org-refile-goto-last-stored ()
+ "Go to the location where the last refile was stored."
+ (interactive)
+ (bookmark-jump "org-refile-last-stored")
+ (message "This is the location of the last refile"))
+
+(defun org-refile-get-location (&optional prompt default-buffer)
+ "Prompt the user for a refile location, using PROMPT."
+ (let ((org-refile-targets org-refile-targets)
+ (org-refile-use-outline-path org-refile-use-outline-path))
+ (setq org-refile-target-table (org-get-refile-targets default-buffer)))
+ (unless org-refile-target-table
+ (error "No refile targets"))
+ (let* ((cbuf (current-buffer))
+ (filename (buffer-file-name (buffer-base-buffer cbuf)))
+ (fname (and filename (file-truename filename)))
+ (tbl (mapcar
+ (lambda (x)
+ (if (not (equal fname (file-truename (nth 1 x))))
+ (cons (concat (car x) " (" (file-name-nondirectory
+ (nth 1 x)) ")")
+ (cdr x))
+ x))
+ org-refile-target-table))
+ (completion-ignore-case t))
+ (assoc (completing-read prompt tbl nil t nil 'org-refile-history)
+ tbl)))
+
;;;; Dynamic blocks
(defun org-find-dblock (name)
(unless (looking-at org-dblock-start-re)
(error "Not at a dynamic block"))
(let* ((begdel (1+ (match-end 0)))
- (name (match-string 1))
+ (name (org-no-properties (match-string 1)))
(params (append (list :name name)
(read (concat "(" (match-string 3) ")")))))
(unless (re-search-forward org-dblock-end-re nil t)
(error "Dynamic block not terminated"))
+ (setq params
+ (append params
+ (list :content (buffer-substring
+ begdel (match-beginning 0)))))
(delete-region begdel (match-beginning 0))
(goto-char begdel)
(open-line 1)
"Update the dynamic block at point
This means to empty the block, parse for parameters and then call
the correct writing function."
- (let* ((pos (point))
- (params (org-prepare-dblock))
- (name (plist-get params :name))
- (cmd (intern (concat "org-dblock-write:" name))))
- (funcall cmd params)
- (goto-char pos)))
+ (save-window-excursion
+ (let* ((pos (point))
+ (line (org-current-line))
+ (params (org-prepare-dblock))
+ (name (plist-get params :name))
+ (cmd (intern (concat "org-dblock-write:" name))))
+ (message "Updating dynamic block `%s' at line %d..." name line)
+ (funcall cmd params)
+ (message "Updating dynamic block `%s' at line %d...done" name line)
+ (goto-char pos))))
(defun org-beginning-of-dblock ()
"Find the beginning of the dynamic block at point.
;;;; Completion
+(defconst org-additional-option-like-keywords
+ '("BEGIN_HTML" "BEGIN_LaTeX" "END_HTML" "END_LaTeX"
+ "ORGTBL" "HTML:" "LaTeX:" "BEGIN:" "END:" "DATE:" "TBLFM"
+ "BEGIN_EXAMPLE" "END_EXAMPLE"))
+
(defun org-complete (&optional arg)
"Perform completion on word at point.
At the beginning of a headline, this completes TODO keywords as given in
If the current word is preceded by \"#+\", completes special words for
setting file options.
In the line after \"#+STARTUP:, complete valid keywords.\"
-At all other locations, this simply calls `ispell-complete-word'."
+At all other locations, this simply calls the value of
+`org-completion-fallback-command'."
(interactive "P")
- (catch 'exit
- (let* ((end (point))
- (beg1 (save-excursion
- (skip-chars-backward "a-zA-Z_@0-9")
+ (org-without-partial-completion
+ (catch 'exit
+ (let* ((end (point))
+ (beg1 (save-excursion
+ (skip-chars-backward (org-re "[:alnum:]_@"))
+ (point)))
+ (beg (save-excursion
+ (skip-chars-backward "a-zA-Z0-9_:$")
(point)))
- (beg (save-excursion
- (skip-chars-backward "a-zA-Z0-9_:$")
- (point)))
- (confirm (lambda (x) (stringp (car x))))
- (searchhead (equal (char-before beg) ?*))
- (tag (equal (char-before beg1) ?:))
- (texp (equal (char-before beg) ?\\))
- (link (equal (char-before beg) ?\[))
- (opt (equal (buffer-substring (max (point-at-bol) (- beg 2))
- beg)
- "#+"))
- (startup (string-match "^#\\+STARTUP:.*"
- (buffer-substring (point-at-bol) (point))))
- (completion-ignore-case opt)
- (type nil)
- (tbl nil)
- (table (cond
- (opt
- (setq type :opt)
- (mapcar (lambda (x)
- (string-match "^#\\+\\(\\([A-Z_]+:?\\).*\\)" x)
- (cons (match-string 2 x) (match-string 1 x)))
- (org-split-string (org-get-current-options) "\n")))
- (startup
- (setq type :startup)
- org-startup-options)
- (link (append org-link-abbrev-alist-local
- org-link-abbrev-alist))
- (texp
- (setq type :tex)
- org-html-entities)
- ((string-match "\\`\\*+[ \t]*\\'"
- (buffer-substring (point-at-bol) beg))
- (setq type :todo)
- (mapcar 'list org-todo-keywords))
- (searchhead
- (setq type :searchhead)
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward org-todo-line-regexp nil t)
- (push (list
- (org-make-org-heading-search-string
- (match-string 3) t))
- tbl)))
- tbl)
- (tag (setq type :tag beg beg1)
- (or org-tag-alist (org-get-buffer-tags)))
- (t (progn (ispell-complete-word arg) (throw 'exit nil)))))
- (pattern (buffer-substring-no-properties beg end))
- (completion (try-completion pattern table confirm)))
- (cond ((eq completion t)
- (if (equal type :opt)
- (insert (substring (cdr (assoc (upcase pattern) table))
- (length pattern)))
- (if (equal type :tag) (insert ":"))))
- ((null completion)
- (message "Can't find completion for \"%s\"" pattern)
- (ding))
- ((not (string= pattern completion))
- (delete-region beg end)
- (if (string-match " +$" completion)
- (setq completion (replace-match "" t t completion)))
- (insert completion)
- (if (get-buffer-window "*Completions*")
- (delete-window (get-buffer-window "*Completions*")))
- (if (assoc completion table)
- (if (eq type :todo) (insert " ")
- (if (eq type :tag) (insert ":"))))
- (if (and (equal type :opt) (assoc completion table))
- (message "%s" (substitute-command-keys
- "Press \\[org-complete] again to insert example settings"))))
- (t
- (message "Making completion list...")
- (let ((list (sort (all-completions pattern table confirm)
- 'string<)))
- (with-output-to-temp-buffer "*Completions*"
- (condition-case nil
- ;; Protection needed for XEmacs and emacs 21
- (display-completion-list list pattern)
- (error (display-completion-list list)))))
- (message "Making completion list...%s" "done"))))))
+ (confirm (lambda (x) (stringp (car x))))
+ (searchhead (equal (char-before beg) ?*))
+ (tag (and (equal (char-before beg1) ?:)
+ (equal (char-after (point-at-bol)) ?*)))
+ (prop (and (equal (char-before beg1) ?:)
+ (not (equal (char-after (point-at-bol)) ?*))))
+ (texp (equal (char-before beg) ?\\))
+ (link (equal (char-before beg) ?\[))
+ (opt (equal (buffer-substring (max (point-at-bol) (- beg 2))
+ beg)
+ "#+"))
+ (startup (string-match "^#\\+STARTUP:.*"
+ (buffer-substring (point-at-bol) (point))))
+ (completion-ignore-case opt)
+ (type nil)
+ (tbl nil)
+ (table (cond
+ (opt
+ (setq type :opt)
+ (append
+ (mapcar
+ (lambda (x)
+ (string-match "^#\\+\\(\\([A-Z_]+:?\\).*\\)" x)
+ (cons (match-string 2 x) (match-string 1 x)))
+ (org-split-string (org-get-current-options) "\n"))
+ (mapcar 'list org-additional-option-like-keywords)))
+ (startup
+ (setq type :startup)
+ org-startup-options)
+ (link (append org-link-abbrev-alist-local
+ org-link-abbrev-alist))
+ (texp
+ (setq type :tex)
+ org-html-entities)
+ ((string-match "\\`\\*+[ \t]+\\'"
+ (buffer-substring (point-at-bol) beg))
+ (setq type :todo)
+ (mapcar 'list org-todo-keywords-1))
+ (searchhead
+ (setq type :searchhead)
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward org-todo-line-regexp nil t)
+ (push (list
+ (org-make-org-heading-search-string
+ (match-string 3) t))
+ tbl)))
+ tbl)
+ (tag (setq type :tag beg beg1)
+ (or org-tag-alist (org-get-buffer-tags)))
+ (prop (setq type :prop beg beg1)
+ (mapcar 'list (org-buffer-property-keys nil t t)))
+ (t (progn
+ (call-interactively org-completion-fallback-command)
+ (throw 'exit nil)))))
+ (pattern (buffer-substring-no-properties beg end))
+ (completion (try-completion pattern table confirm)))
+ (cond ((eq completion t)
+ (if (not (assoc (upcase pattern) table))
+ (message "Already complete")
+ (if (equal type :opt)
+ (insert (substring (cdr (assoc (upcase pattern) table))
+ (length pattern)))
+ (if (memq type '(:tag :prop)) (insert ":")))))
+ ((null completion)
+ (message "Can't find completion for \"%s\"" pattern)
+ (ding))
+ ((not (string= pattern completion))
+ (delete-region beg end)
+ (if (string-match " +$" completion)
+ (setq completion (replace-match "" t t completion)))
+ (insert completion)
+ (if (get-buffer-window "*Completions*")
+ (delete-window (get-buffer-window "*Completions*")))
+ (if (assoc completion table)
+ (if (eq type :todo) (insert " ")
+ (if (memq type '(:tag :prop)) (insert ":"))))
+ (if (and (equal type :opt) (assoc completion table))
+ (message "%s" (substitute-command-keys
+ "Press \\[org-complete] again to insert example settings"))))
+ (t
+ (message "Making completion list...")
+ (let ((list (sort (all-completions pattern table confirm)
+ 'string<)))
+ (with-output-to-temp-buffer "*Completions*"
+ (condition-case nil
+ ;; Protection needed for XEmacs and emacs 21
+ (display-completion-list list pattern)
+ (error (display-completion-list list)))))
+ (message "Making completion list...%s" "done")))))))
;;;; TODO, DEADLINE, Comments
(interactive)
(save-excursion
(org-back-to-heading)
- (if (looking-at (concat outline-regexp
- "\\( +\\<" org-comment-string "\\>\\)"))
- (replace-match "" t t nil 1)
- (if (looking-at outline-regexp)
- (progn
- (goto-char (match-end 0))
- (insert " " org-comment-string))))))
+ (let (case-fold-search)
+ (if (looking-at (concat outline-regexp
+ "\\( *\\<" org-comment-string "\\>[ \t]*\\)"))
+ (replace-match "" t t nil 1)
+ (if (looking-at outline-regexp)
+ (progn
+ (goto-char (match-end 0))
+ (insert org-comment-string " ")))))))
(defvar org-last-todo-state-is-todo nil
"This is non-nil when the last TODO state change led to a TODO state.
If the last change removed the TODO tag or switched to DONE, then
this is nil.")
+(defvar org-setting-tags nil) ; dynamically skiped
+
+;; FIXME: better place
+(defun org-property-or-variable-value (var &optional inherit)
+ "Check if there is a property fixing the value of VAR.
+If yes, return this value. If not, return the current value of the variable."
+ (let ((prop (org-entry-get nil (symbol-name var) inherit)))
+ (if (and prop (stringp prop) (string-match "\\S-" prop))
+ (read prop)
+ (symbol-value var))))
+
+(defun org-parse-local-options (string var)
+ "Parse STRING for startup setting relevant for variable VAR."
+ (let ((rtn (symbol-value var))
+ e opts)
+ (save-match-data
+ (if (or (not string) (not (string-match "\\S-" string)))
+ rtn
+ (setq opts (delq nil (mapcar (lambda (x)
+ (setq e (assoc x org-startup-options))
+ (if (eq (nth 1 e) var) e nil))
+ (org-split-string string "[ \t]+"))))
+ (if (not opts)
+ rtn
+ (setq rtn nil)
+ (while (setq e (pop opts))
+ (if (not (nth 3 e))
+ (setq rtn (nth 2 e))
+ (if (not (listp rtn)) (setq rtn nil))
+ (push (nth 2 e) rtn)))
+ rtn)))))
+
+(defvar org-blocker-hook nil
+ "Hook for functions that are allowed to block a state change.
+
+Each function gets as its single argument a property list, see
+`org-trigger-hook' for more information about this list.
+
+If any of the functions in this hook returns nil, the state change
+is blocked.")
+
+(defvar org-trigger-hook nil
+ "Hook for functions that are triggered by a state change.
+
+Each function gets as its single argument a property list with at least
+the following elements:
+
+ (:type type-of-change :position pos-at-entry-start
+ :from old-state :to new-state)
+
+Depending on the type, more properties may be present.
+
+This mechanism is currently implemented for:
+
+TODO state changes
+------------------
+:type todo-state-change
+:from previous state (keyword as a string), or nil
+:to new state (keyword as a string), or nil")
+
+
(defun org-todo (&optional arg)
"Change the TODO state of an item.
The state of an item is given by a keyword at the start of the heading,
'none -> empty state
\"\"(empty string) -> switch to empty state
'done -> switch to DONE
+'nextset -> switch to the next set of keywords
+'previousset -> switch to the previous set of keywords
\"WAITING\" -> switch to the specified keyword, but only if it
really is a member of `org-todo-keywords'."
(interactive "P")
(save-excursion
- (org-back-to-heading)
- (if (looking-at outline-regexp) (goto-char (match-end 0)))
- (or (looking-at (concat " +" org-todo-regexp " *"))
- (looking-at " *"))
- (let* ((this (match-string 1))
- (last-state (or this ""))
- (completion-ignore-case t)
- (member (member this org-todo-keywords))
- (tail (cdr member))
- (state (cond
- ((equal arg '(4))
- ;; Read a state with completion
- (completing-read "State: " (mapcar (lambda(x) (list x))
- org-todo-keywords)
- nil t))
- ((eq arg 'right)
- (if this
- (if tail (car tail) nil)
- (car org-todo-keywords)))
- ((eq arg 'left)
- (if (equal member org-todo-keywords)
- nil
+ (catch 'exit
+ (org-back-to-heading)
+ (if (looking-at outline-regexp) (goto-char (1- (match-end 0))))
+ (or (looking-at (concat " +" org-todo-regexp " *"))
+ (looking-at " *"))
+ (let* ((match-data (match-data))
+ (startpos (point-at-bol))
+ (logging (save-match-data (org-entry-get nil "LOGGING" t)))
+ (org-log-done org-log-done)
+ (org-log-repeat org-log-repeat)
+ (org-todo-log-states org-todo-log-states)
+ (this (match-string 1))
+ (hl-pos (match-beginning 0))
+ (head (org-get-todo-sequence-head this))
+ (ass (assoc head org-todo-kwd-alist))
+ (interpret (nth 1 ass))
+ (done-word (nth 3 ass))
+ (final-done-word (nth 4 ass))
+ (last-state (or this ""))
+ (completion-ignore-case t)
+ (member (member this org-todo-keywords-1))
+ (tail (cdr member))
+ (state (cond
+ ((and org-todo-key-trigger
+ (or (and (equal arg '(4)) (eq org-use-fast-todo-selection 'prefix))
+ (and (not arg) org-use-fast-todo-selection
+ (not (eq org-use-fast-todo-selection 'prefix)))))
+ ;; Use fast selection
+ (org-fast-todo-selection))
+ ((and (equal arg '(4))
+ (or (not org-use-fast-todo-selection)
+ (not org-todo-key-trigger)))
+ ;; Read a state with completion
+ (completing-read "State: " (mapcar (lambda(x) (list x))
+ org-todo-keywords-1)
+ nil t))
+ ((eq arg 'right)
(if this
- (nth (- (length org-todo-keywords) (length tail) 2)
- org-todo-keywords)
- org-done-string)))
- (arg
- ;; user requests a specific state
- (cond
- ((equal arg "") nil)
- ((eq arg 'none) nil)
- ((eq arg 'done) (org-last org-todo-keywords))
- ((car (member arg org-todo-keywords)))
- ((nth (1- (prefix-numeric-value arg))
- org-todo-keywords))))
- ((null member) (car org-todo-keywords))
- ((null tail) nil) ;; -> first entry
- ((eq org-todo-interpretation 'sequence)
- (car tail))
- ((memq org-todo-interpretation '(type priority))
- (if (eq this-command last-command)
- (car tail)
- (if (> (length tail) 0) org-done-string nil)))
- (t nil)))
- (next (if state (concat " " state " ") " "))
- dostates)
- (replace-match next t t)
- (setq org-last-todo-state-is-todo
- (not (equal state org-done-string)))
- (when org-log-done
- (setq dostates (and (eq org-todo-interpretation 'sequence)
- (listp org-log-done) (memq 'state org-log-done)))
+ (if tail (car tail) nil)
+ (car org-todo-keywords-1)))
+ ((eq arg 'left)
+ (if (equal member org-todo-keywords-1)
+ nil
+ (if this
+ (nth (- (length org-todo-keywords-1) (length tail) 2)
+ org-todo-keywords-1)
+ (org-last org-todo-keywords-1))))
+ ((and (eq org-use-fast-todo-selection t) (equal arg '(4))
+ (setq arg nil))) ; hack to fall back to cycling
+ (arg
+ ;; user or caller requests a specific state
+ (cond
+ ((equal arg "") nil)
+ ((eq arg 'none) nil)
+ ((eq arg 'done) (or done-word (car org-done-keywords)))
+ ((eq arg 'nextset)
+ (or (car (cdr (member head org-todo-heads)))
+ (car org-todo-heads)))
+ ((eq arg 'previousset)
+ (let ((org-todo-heads (reverse org-todo-heads)))
+ (or (car (cdr (member head org-todo-heads)))
+ (car org-todo-heads))))
+ ((car (member arg org-todo-keywords-1)))
+ ((nth (1- (prefix-numeric-value arg))
+ org-todo-keywords-1))))
+ ((null member) (or head (car org-todo-keywords-1)))
+ ((equal this final-done-word) nil) ;; -> make empty
+ ((null tail) nil) ;; -> first entry
+ ((eq interpret 'sequence)
+ (car tail))
+ ((memq interpret '(type priority))
+ (if (eq this-command last-command)
+ (car tail)
+ (if (> (length tail) 0)
+ (or done-word (car org-done-keywords))
+ nil)))
+ (t nil)))
+ (next (if state (concat " " state " ") " "))
+ (change-plist (list :type 'todo-state-change :from this :to state
+ :position startpos))
+ dolog now-done-p)
+ (when org-blocker-hook
+ (unless (save-excursion
+ (save-match-data
+ (run-hook-with-args-until-failure
+ 'org-blocker-hook change-plist)))
+ (if (interactive-p)
+ (error "TODO state change from %s to %s blocked" this state)
+ ;; fail silently
+ (message "TODO state change from %s to %s blocked" this state)
+ (throw 'exit nil))))
+ (store-match-data match-data)
+ (replace-match next t t)
+ (unless (pos-visible-in-window-p hl-pos)
+ (message "TODO state changed to %s" (org-trim next)))
+ (unless head
+ (setq head (org-get-todo-sequence-head state)
+ ass (assoc head org-todo-kwd-alist)
+ interpret (nth 1 ass)
+ done-word (nth 3 ass)
+ final-done-word (nth 4 ass)))
+ (when (memq arg '(nextset previousset))
+ (message "Keyword-Set %d/%d: %s"
+ (- (length org-todo-sets) -1
+ (length (memq (assoc state org-todo-sets) org-todo-sets)))
+ (length org-todo-sets)
+ (mapconcat 'identity (assoc state org-todo-sets) " ")))
+ (setq org-last-todo-state-is-todo
+ (not (member state org-done-keywords)))
+ (setq now-done-p (and (member state org-done-keywords)
+ (not (member this org-done-keywords))))
+ (and logging (org-local-logging logging))
+ (when (and (or org-todo-log-states org-log-done)
+ (not (memq arg '(nextset previousset))))
+ ;; we need to look at recording a time and note
+ (setq dolog (or (nth 1 (assoc state org-todo-log-states))
+ (nth 2 (assoc this org-todo-log-states))))
+ (when (and state
+ (member state org-not-done-keywords)
+ (not (member this org-not-done-keywords)))
+ ;; This is now a todo state and was not one before
+ ;; If there was a CLOSED time stamp, get rid of it.
+ (org-add-planning-info nil nil 'closed))
+ (when (and now-done-p org-log-done)
+ ;; It is now done, and it was not done before
+ (org-add-planning-info 'closed (org-current-time))
+ (if (and (not dolog) (eq 'note org-log-done))
+ (org-add-log-maybe 'done state 'findpos 'note)))
+ (when (and state dolog)
+ ;; This is a non-nil state, and we need to log it
+ (org-add-log-maybe 'state state 'findpos dolog)))
+ ;; Fixup tag positioning
+ (and org-auto-align-tags (not org-setting-tags) (org-set-tags nil t))
+ (run-hooks 'org-after-todo-state-change-hook)
+ (if (and arg (not (member state org-done-keywords)))
+ (setq head (org-get-todo-sequence-head state)))
+ (put-text-property (point-at-bol) (point-at-eol) 'org-todo-head head)
+ ;; Do we need to trigger a repeat?
+ (when now-done-p (org-auto-repeat-maybe state))
+ ;; Fixup cursor location if close to the keyword
+ (if (and (outline-on-heading-p)
+ (not (bolp))
+ (save-excursion (beginning-of-line 1)
+ (looking-at org-todo-line-regexp))
+ (< (point) (+ 2 (or (match-end 2) (match-end 1)))))
+ (progn
+ (goto-char (or (match-end 2) (match-end 1)))
+ (just-one-space)))
+ (when org-trigger-hook
+ (save-excursion
+ (run-hook-with-args 'org-trigger-hook change-plist)))))))
+
+(defun org-local-logging (value)
+ "Get logging settings from a property VALUE."
+ (let* (words w a)
+ ;; directly set the variables, they are already local.
+ (setq org-log-done nil
+ org-log-repeat nil
+ org-todo-log-states nil)
+ (setq words (org-split-string value))
+ (while (setq w (pop words))
+ (cond
+ ((setq a (assoc w org-startup-options))
+ (and (member (nth 1 a) '(org-log-done org-log-repeat))
+ (set (nth 1 a) (nth 2 a))))
+ ((setq a (org-extract-log-state-settings w))
+ (and (member (car a) org-todo-keywords-1)
+ (push a org-todo-log-states)))))))
+
+(defun org-get-todo-sequence-head (kwd)
+ "Return the head of the TODO sequence to which KWD belongs.
+If KWD is not set, check if there is a text property remembering the
+right sequence."
+ (let (p)
+ (cond
+ ((not kwd)
+ (or (get-text-property (point-at-bol) 'org-todo-head)
+ (progn
+ (setq p (next-single-property-change (point-at-bol) 'org-todo-head
+ nil (point-at-eol)))
+ (get-text-property p 'org-todo-head))))
+ ((not (member kwd org-todo-keywords-1))
+ (car org-todo-keywords-1))
+ (t (nth 2 (assoc kwd org-todo-kwd-alist))))))
+
+(defun org-fast-todo-selection ()
+ "Fast TODO keyword selection with single keys.
+Returns the new TODO keyword, or nil if no state change should occur."
+ (let* ((fulltable org-todo-key-alist)
+ (done-keywords org-done-keywords) ;; needed for the faces.
+ (maxlen (apply 'max (mapcar
+ (lambda (x)
+ (if (stringp (car x)) (string-width (car x)) 0))
+ fulltable)))
+ (expert nil)
+ (fwidth (+ maxlen 3 1 3))
+ (ncol (/ (- (window-width) 4) fwidth))
+ tg cnt e c tbl
+ groups ingroup)
+ (save-window-excursion
+ (if expert
+ (set-buffer (get-buffer-create " *Org todo*"))
+ (org-switch-to-buffer-other-window (get-buffer-create " *Org todo*")))
+ (erase-buffer)
+ (org-set-local 'org-done-keywords done-keywords)
+ (setq tbl fulltable cnt 0)
+ (while (setq e (pop tbl))
(cond
- ((and state (not this))
- (org-add-planning-info nil nil 'closed)
- (and dostates (org-add-log-maybe 'state state 'findpos)))
- ((and state dostates)
- (org-add-log-maybe 'state state 'findpos))
- ((equal state org-done-string)
- ;; Planning info calls the note-setting command.
- (org-add-planning-info 'closed (org-current-time)
- (if (org-get-repeat) nil 'scheduled))
- (org-add-log-maybe 'done state 'findpos))))
- ;; Fixup tag positioning
- (and org-auto-align-tags (org-set-tags nil t))
- (run-hooks 'org-after-todo-state-change-hook)
- (and (equal state org-done-string) (org-auto-repeat-maybe))
- ))
- ;; Fixup cursor location if close to the keyword
- (if (and (outline-on-heading-p)
- (not (bolp))
- (save-excursion (beginning-of-line 1)
- (looking-at org-todo-line-regexp))
- (< (point) (+ 2 (or (match-end 2) (match-end 1)))))
- (progn
- (goto-char (or (match-end 2) (match-end 1)))
- (just-one-space))))
+ ((equal e '(:startgroup))
+ (push '() groups) (setq ingroup t)
+ (when (not (= cnt 0))
+ (setq cnt 0)
+ (insert "\n"))
+ (insert "{ "))
+ ((equal e '(:endgroup))
+ (setq ingroup nil cnt 0)
+ (insert "}\n"))
+ (t
+ (setq tg (car e) c (cdr e))
+ (if ingroup (push tg (car groups)))
+ (setq tg (org-add-props tg nil 'face
+ (org-get-todo-face tg)))
+ (if (and (= cnt 0) (not ingroup)) (insert " "))
+ (insert "[" c "] " tg (make-string
+ (- fwidth 4 (length tg)) ?\ ))
+ (when (= (setq cnt (1+ cnt)) ncol)
+ (insert "\n")
+ (if ingroup (insert " "))
+ (setq cnt 0)))))
+ (insert "\n")
+ (goto-char (point-min))
+ (if (and (not expert) (fboundp 'fit-window-to-buffer))
+ (fit-window-to-buffer))
+ (message "[a-z..]:Set [SPC]:clear")
+ (setq c (let ((inhibit-quit t)) (read-char-exclusive)))
+ (cond
+ ((or (= c ?\C-g)
+ (and (= c ?q) (not (rassoc c fulltable))))
+ (setq quit-flag t))
+ ((= c ?\ ) nil)
+ ((setq e (rassoc c fulltable) tg (car e))
+ tg)
+ (t (setq quit-flag t))))))
(defun org-get-repeat ()
- "Return the REPEAT statement of this entry."
+ "Check if tere is a deadline/schedule with repeater in this entry."
(save-match-data
(save-excursion
(org-back-to-heading t)
(defvar org-last-changed-timestamp)
(defvar org-log-post-message)
-(defun org-auto-repeat-maybe ()
- "Check if the current headline contains a REPEAT key.
-If yes, set TODO state back to what it was and change any SCHEDULED
-or DEADLINE times the new date.
-This function should be run in the `org-after-todo-state-change-hook'."
+(defvar org-log-note-purpose)
+(defun org-auto-repeat-maybe (done-word)
+ "Check if the current headline contains a repeated deadline/schedule.
+If yes, set TODO state back to what it was and change the base date
+of repeating deadline/scheduled time stamps to new date.
+This function is run automatically after each state change to a DONE state."
;; last-state is dynamically scoped into this function
- (let ((repeat (org-get-repeat))
- (whata '(("d" . day) ("m" . month) ("y" . year)))
- (msg "Entry repeats: ")
- (org-log-done)
- re type n what start)
+ (let* ((repeat (org-get-repeat))
+ (aa (assoc last-state org-todo-kwd-alist))
+ (interpret (nth 1 aa))
+ (head (nth 2 aa))
+ (whata '(("d" . day) ("m" . month) ("y" . year)))
+ (msg "Entry repeats: ")
+ (org-log-done nil)
+ (org-todo-log-states nil)
+ (nshiftmax 10) (nshift 0)
+ re type n what ts mb0 time)
(when repeat
- (org-todo (if (eq 'org-todo-interpretation 'type)
- last-state
- (car org-todo-keywords)))
- (unless (memq 'org-add-log-note (default-value 'post-command-hook))
- ;; Make sure a note is taken
- (let ((org-log-done '(done)))
- (org-add-log-maybe 'done org-done-string 'findpos)))
+ (if (eq org-log-repeat t) (setq org-log-repeat 'state))
+ (org-todo (if (eq interpret 'type) last-state head))
+ (when (and org-log-repeat
+ (or (not (memq 'org-add-log-note
+ (default-value 'post-command-hook)))
+ (eq org-log-note-purpose 'done)))
+ ;; Make sure a note is taken;
+ (org-add-log-maybe 'state (or done-word (car org-done-keywords))
+ 'findpos org-log-repeat))
(org-back-to-heading t)
(org-add-planning-info nil nil 'closed)
(setq re (concat "\\(" org-scheduled-time-regexp "\\)\\|\\("
- org-deadline-time-regexp "\\)"))
+ org-deadline-time-regexp "\\)\\|\\("
+ org-ts-regexp "\\)"))
(while (re-search-forward
re (save-excursion (outline-next-heading) (point)) t)
- (setq type (if (match-end 1) org-scheduled-string org-deadline-string)
- start 0)
- (while (string-match "\\([-+]?[0-9]+\\)\\([dwmy]\\)" repeat start)
- (setq start (match-end 0)
- n (string-to-number (match-string 1 repeat))
- what (match-string 2 repeat))
+ (setq type (if (match-end 1) org-scheduled-string
+ (if (match-end 3) org-deadline-string "Plain:"))
+ ts (match-string (if (match-end 2) 2 (if (match-end 4) 4 0)))
+ mb0 (match-beginning 0))
+ (when (string-match "\\([.+]\\)?\\(\\+[0-9]+\\)\\([dwmy]\\)" ts)
+ (setq n (string-to-number (match-string 2 ts))
+ what (match-string 3 ts))
(if (equal what "w") (setq n (* n 7) what "d"))
- (org-timestamp-change n (cdr (assoc what whata))))
- (setq msg (concat msg type org-last-changed-timestamp " ")))
+ ;; Preparation, see if we need to modify the start date for the change
+ (when (match-end 1)
+ (setq time (save-match-data (org-time-string-to-time ts)))
+ (cond
+ ((equal (match-string 1 ts) ".")
+ ;; Shift starting date to today
+ (org-timestamp-change
+ (- (time-to-days (current-time)) (time-to-days time))
+ 'day))
+ ((equal (match-string 1 ts) "+")
+ (while (< (time-to-days time) (time-to-days (current-time)))
+ (when (= (incf nshift) nshiftmax)
+ (or (y-or-n-p (message "%d repeater intervals were not enough to shift date past today. Continue? " nshift))
+ (error "Abort")))
+ (org-timestamp-change n (cdr (assoc what whata)))
+ (sit-for .0001) ;; so we can watch the date shifting
+ (org-at-timestamp-p t)
+ (setq ts (match-string 1))
+ (setq time (save-match-data (org-time-string-to-time ts))))
+ (org-timestamp-change (- n) (cdr (assoc what whata)))
+ ;; rematch, so that we have everything in place for the real shift
+ (org-at-timestamp-p t)
+ (setq ts (match-string 1))
+ (string-match "\\([.+]\\)?\\(\\+[0-9]+\\)\\([dwmy]\\)" ts))))
+ (org-timestamp-change n (cdr (assoc what whata)))
+ (setq msg (concat msg type org-last-changed-timestamp " "))))
(setq org-log-post-message msg)
- (message msg))))
+ (message "%s" msg))))
(defun org-show-todo-tree (arg)
"Make a compact tree which shows all headlines marked with TODO.
The tree will show the lines where the regexp matches, and all higher
headlines above the match.
-With \\[universal-argument] prefix, also show the DONE entries.
+With a \\[universal-argument] prefix, also show the DONE entries.
With a numeric prefix N, construct a sparse tree for the Nth element
-of `org-todo-keywords'."
+of `org-todo-keywords-1'."
(interactive "P")
(let ((case-fold-search nil)
(kwd-re
(cond ((null arg) org-not-done-regexp)
- ((equal arg '(4)) org-todo-regexp)
- ((<= (prefix-numeric-value arg) (length org-todo-keywords))
+ ((equal arg '(4))
+ (let ((kwd (completing-read "Keyword (or KWD1|KWD2|...): "
+ (mapcar 'list org-todo-keywords-1))))
+ (concat "\\("
+ (mapconcat 'identity (org-split-string kwd "|") "\\|")
+ "\\)\\>")))
+ ((<= (prefix-numeric-value arg) (length org-todo-keywords-1))
(regexp-quote (nth (1- (prefix-numeric-value arg))
- org-todo-keywords)))
+ org-todo-keywords-1)))
(t (error "Invalid prefix argument: %s" arg)))))
(message "%d TODO entries found"
- (org-occur (concat "^" outline-regexp " +" kwd-re )))))
+ (org-occur (concat "^" outline-regexp " *" kwd-re )))))
-(defun org-deadline ()
- "Insert the DEADLINE: string to make a deadline.
-A timestamp is also inserted - use \\[org-timestamp-up] and \\[org-timestamp-down]
-to modify it to the correct date."
- (interactive)
- (org-add-planning-info 'deadline nil 'closed))
+(defun org-deadline (&optional remove)
+ "Insert the \"DEADLINE:\" string with a timestamp to make a deadline.
+With argument REMOVE, remove any deadline from the item."
+ (interactive "P")
+ (if remove
+ (progn
+ (org-remove-timestamp-with-keyword org-deadline-string)
+ (message "Item no longer has a deadline."))
+ (org-add-planning-info 'deadline nil 'closed)))
-(defun org-schedule ()
- "Insert the SCHEDULED: string to schedule a TODO item.
-A timestamp is also inserted - use \\[org-timestamp-up] and \\[org-timestamp-down]
-to modify it to the correct date."
- (interactive)
- (org-add-planning-info 'scheduled nil 'closed))
+(defun org-schedule (&optional remove)
+ "Insert the SCHEDULED: string with a timestamp to schedule a TODO item.
+With argument REMOVE, remove any scheduling date from the item."
+ (interactive "P")
+ (if remove
+ (progn
+ (org-remove-timestamp-with-keyword org-scheduled-string)
+ (message "Item is no longer scheduled."))
+ (org-add-planning-info 'scheduled nil 'closed)))
+
+(defun org-remove-timestamp-with-keyword (keyword)
+ "Remove all time stamps with KEYWORD in the current entry."
+ (let ((re (concat "\\<" (regexp-quote keyword) " +<[^>\n]+>[ \t]*"))
+ beg)
+ (save-excursion
+ (org-back-to-heading t)
+ (setq beg (point))
+ (org-end-of-subtree t t)
+ (while (re-search-backward re beg t)
+ (replace-match "")
+ (unless (string-match "\\S-" (buffer-substring (point-at-bol) (point)))
+ (delete-region (point-at-bol) (min (1+ (point)) (point-max))))))))
(defun org-add-planning-info (what &optional time &rest remove)
"Insert new timestamp with keyword in the line directly after the headline.
REMOVE indicates what kind of entries to remove. An old WHAT entry will also
be removed."
(interactive)
- (let (org-time-was-given)
+ (let (org-time-was-given org-end-time-was-given)
(when what (setq time (or time (org-read-date nil 'to-time))))
(when (and org-insert-labeled-timestamps-at-point
(member what '(scheduled deadline)))
(insert
(if (eq what 'scheduled) org-scheduled-string org-deadline-string) " ")
- (org-insert-time-stamp time org-time-was-given)
+ (org-insert-time-stamp time org-time-was-given
+ nil nil nil (list org-end-time-was-given))
(setq what nil))
(save-excursion
(save-restriction
(looking-at (concat outline-regexp "\\( *\\)[^\r\n]*"))
(goto-char (match-end 1))
(setq col (current-column))
- (goto-char (1+ (match-end 0)))
+ (goto-char (match-end 0))
+ (if (eobp) (insert "\n") (forward-char 1))
(if (and (not (looking-at outline-regexp))
(looking-at (concat "[^\r\n]*?" org-keyword-time-regexp
"[^\r\n]*"))
(not (equal (match-string 1) org-clock-string)))
(narrow-to-region (match-beginning 0) (match-end 0))
- (insert "\n")
+ (insert-before-markers "\n")
(backward-char 1)
(narrow-to-region (point) (point))
(indent-to-column col))
((eq what 'deadline) org-deadline-string)
((eq what 'closed) org-closed-string))
" ")
- (org-insert-time-stamp time
- (or org-time-was-given (eq what 'closed))
- (eq what 'closed))
+ (setq ts (org-insert-time-stamp
+ time
+ (or org-time-was-given
+ (and (eq what 'closed) org-log-done-with-time))
+ (eq what 'closed)
+ nil nil (list org-end-time-was-given)))
(end-of-line 1))
(goto-char (point-min))
(widen)
(defvar org-log-note-marker (make-marker))
(defvar org-log-note-purpose nil)
(defvar org-log-note-state nil)
+(defvar org-log-note-how nil)
(defvar org-log-note-window-configuration nil)
(defvar org-log-note-return-to (make-marker))
(defvar org-log-post-message nil
"Message to be displayed after a log note has been stored.
The auto-repeater uses this.")
-(defun org-add-log-maybe (&optional purpose state findpos)
+(defun org-add-log-maybe (&optional purpose state findpos how)
+ "Set up the post command hook to take a note.
+If this is about to TODO state change, the new state is expected in STATE.
+When FINDPOS is non-nil, find the correct position for the note in
+the current entry. If not, assume that it can be inserted at point."
(save-excursion
- (when (and (listp org-log-done)
- (memq purpose org-log-done))
- (when findpos
- (org-back-to-heading t)
- (looking-at (concat outline-regexp "\\( *\\)[^\r\n]*"
- "\\(\n[^\r\n]*?" org-keyword-time-not-clock-regexp
- "[^\r\n]*\\)?"))
- (goto-char (match-end 0)))
- (move-marker org-log-note-marker (point))
- (setq org-log-note-purpose purpose)
- (setq org-log-note-state state)
- (add-hook 'post-command-hook 'org-add-log-note 'append))))
+ (when findpos
+ (org-back-to-heading t)
+ (looking-at (concat outline-regexp "\\( *\\)[^\r\n]*"
+ "\\(\n[^\r\n]*?" org-keyword-time-not-clock-regexp
+ "[^\r\n]*\\)?"))
+ (goto-char (match-end 0))
+ (unless org-log-states-order-reversed
+ (and (= (char-after) ?\n) (forward-char 1))
+ (org-skip-over-state-notes)
+ (skip-chars-backward " \t\n\r")))
+ (move-marker org-log-note-marker (point))
+ (setq org-log-note-purpose purpose
+ org-log-note-state state
+ org-log-note-how how)
+ (add-hook 'post-command-hook 'org-add-log-note 'append)))
+
+(defun org-skip-over-state-notes ()
+ "Skip past the list of State notes in an entry."
+ (if (looking-at "\n[ \t]*- State") (forward-char 1))
+ (while (looking-at "[ \t]*- State")
+ (condition-case nil
+ (org-next-item)
+ (error (org-end-of-item)))))
(defun org-add-log-note (&optional purpose)
"Pop up a window for taking a note, and add this note later at point."
(move-marker org-log-note-return-to (point))
(switch-to-buffer (marker-buffer org-log-note-marker))
(goto-char org-log-note-marker)
- (switch-to-buffer-other-window "*Org Note*")
+ (org-switch-to-buffer-other-window "*Org Note*")
(erase-buffer)
- (let ((org-inhibit-startup t)) (org-mode))
- (insert (format "# Insert note for %s, finish with C-c C-c.\n\n"
- (cond
- ((eq org-log-note-purpose 'clock-out) "stopped clock")
- ((eq org-log-note-purpose 'done) "closed todo item")
- ((eq org-log-note-purpose 'state) "state change")
+ (if (memq org-log-note-how '(time state)) ; FIXME: time or state????????????
+ (org-store-log-note)
+ (let ((org-inhibit-startup t)) (org-mode))
+ (insert (format "# Insert note for %s.
+# Finish with C-c C-c, or cancel with C-c C-k.\n\n"
+ (cond
+ ((eq org-log-note-purpose 'clock-out) "stopped clock")
+ ((eq org-log-note-purpose 'done) "closed todo item")
+ ((eq org-log-note-purpose 'state)
+ (format "state change to \"%s\"" org-log-note-state))
(t (error "This should not happen")))))
- (org-set-local 'org-finish-function 'org-store-log-note))
+ (org-set-local 'org-finish-function 'org-store-log-note)))
(defun org-store-log-note ()
"Finish taking a log note, and insert it to where it belongs."
(note (cdr (assq org-log-note-purpose org-log-note-headings)))
lines ind)
(kill-buffer (current-buffer))
- (if (string-match "^#.*\n[ \t\n]*" txt)
- (setq txt (replace-match "" t t txt)))
+ (while (string-match "\\`#.*\n[ \t\n]*" txt)
+ (setq txt (replace-match "" t t txt)))
(if (string-match "\\s-+\\'" txt)
(setq txt (replace-match "" t t txt)))
(setq lines (org-split-string txt "\n"))
"")))))
(if lines (setq note (concat note " \\\\")))
(push note lines))
- (save-excursion
- (set-buffer (marker-buffer org-log-note-marker))
+ (when (or current-prefix-arg org-note-abort) (setq lines nil))
+ (when lines
(save-excursion
- (goto-char org-log-note-marker)
- (move-marker org-log-note-marker nil)
- (end-of-line 1)
- (if (not (bolp)) (insert "\n")) (indent-relative nil)
- (setq ind (concat (buffer-substring (point-at-bol) (point)) " "))
- (insert " - " (pop lines))
- (while lines
- (insert "\n" ind (pop lines))))))
+ (set-buffer (marker-buffer org-log-note-marker))
+ (save-excursion
+ (goto-char org-log-note-marker)
+ (move-marker org-log-note-marker nil)
+ (end-of-line 1)
+ (if (not (bolp)) (let ((inhibit-read-only t)) (insert "\n")))
+ (indent-relative nil)
+ (insert "- " (pop lines))
+ (org-indent-line-function)
+ (beginning-of-line 1)
+ (looking-at "[ \t]*")
+ (setq ind (concat (match-string 0) " "))
+ (end-of-line 1)
+ (while lines (insert "\n" ind (pop lines)))))))
(set-window-configuration org-log-note-window-configuration)
(with-current-buffer (marker-buffer org-log-note-return-to)
(goto-char org-log-note-return-to))
(move-marker org-log-note-return-to nil)
- (and org-log-post-message (message org-log-post-message)))
-
-(defvar org-occur-highlights nil)
+ (and org-log-post-message (message "%s" org-log-post-message)))
+
+;; FIXME: what else would be useful?
+;; - priority
+;; - date
+
+(defun org-sparse-tree (&optional arg)
+ "Create a sparse tree, prompt for the details.
+This command can create sparse trees. You first need to select the type
+of match used to create the tree:
+
+t Show entries with a specific TODO keyword.
+T Show entries selected by a tags match.
+p Enter a property name and its value (both with completion on existing
+ names/values) and show entries with that property.
+r Show entries matching a regular expression
+d Show deadlines due within `org-deadline-warning-days'."
+ (interactive "P")
+ (let (ans kwd value)
+ (message "Sparse tree: [/]regexp [t]odo-kwd [T]ag [p]roperty [d]eadlines [b]efore-date")
+ (setq ans (read-char-exclusive))
+ (cond
+ ((equal ans ?d)
+ (call-interactively 'org-check-deadlines))
+ ((equal ans ?b)
+ (call-interactively 'org-check-before-date))
+ ((equal ans ?t)
+ (org-show-todo-tree '(4)))
+ ((equal ans ?T)
+ (call-interactively 'org-tags-sparse-tree))
+ ((member ans '(?p ?P))
+ (setq kwd (completing-read "Property: "
+ (mapcar 'list (org-buffer-property-keys))))
+ (setq value (completing-read "Value: "
+ (mapcar 'list (org-property-values kwd))))
+ (unless (string-match "\\`{.*}\\'" value)
+ (setq value (concat "\"" value "\"")))
+ (org-tags-sparse-tree arg (concat kwd "=" value)))
+ ((member ans '(?r ?R ?/))
+ (call-interactively 'org-occur))
+ (t (error "No such sparse tree command \"%c\"" ans)))))
+
+(defvar org-occur-highlights nil
+ "List of overlays used for occur matches.")
(make-variable-buffer-local 'org-occur-highlights)
+(defvar org-occur-parameters nil
+ "Parameters of the active org-occur calls.
+This is a list, each call to org-occur pushes as cons cell,
+containing the regular expression and the callback, onto the list.
+The list can contain several entries if `org-occur' has been called
+several time with the KEEP-PREVIOUS argument. Otherwise, this list
+will only contain one set of parameters. When the highlights are
+removed (for example with `C-c C-c', or with the next edit (depending
+on `org-remove-highlights-with-change'), this variable is emptied
+as well.")
+(make-variable-buffer-local 'org-occur-parameters)
(defun org-occur (regexp &optional keep-previous callback)
"Make a compact tree which shows all matches of REGEXP.
If CALLBACK is non-nil, it is a function which is called to confirm
that the match should indeed be shown."
(interactive "sRegexp: \nP")
- (or keep-previous (org-remove-occur-highlights nil nil t))
+ (unless keep-previous
+ (org-remove-occur-highlights nil nil t))
+ (push (cons regexp callback) org-occur-parameters)
(let ((cnt 0))
(save-excursion
(goto-char (point-min))
(when (or (not callback)
(save-match-data (funcall callback)))
(setq cnt (1+ cnt))
- (org-highlight-new-match (match-beginning 0) (match-end 0))
+ (when org-highlight-sparse-tree-matches
+ (org-highlight-new-match (match-beginning 0) (match-end 0)))
(org-show-context 'occur-tree))))
(when org-remove-highlights-with-change
(org-add-hook 'before-change-functions 'org-remove-occur-highlights
(let ((heading-p (org-on-heading-p t))
(hierarchy-p (org-get-alist-option org-show-hierarchy-above key))
(following-p (org-get-alist-option org-show-following-heading key))
+ (entry-p (org-get-alist-option org-show-entry-below key))
(siblings-p (org-get-alist-option org-show-siblings key)))
(catch 'exit
;; Show heading or entry text
- (if heading-p
+ (if (and heading-p (not entry-p))
(org-flag-heading nil) ; only show the heading
- (and (or (org-invisible-p) (org-invisible-p2))
+ (and (or entry-p (org-invisible-p) (org-invisible-p2))
(org-show-hidden-entry))) ; show entire entry
(when following-p
;; Show next sibling, or heading below text
(unless org-inhibit-highlight-removal
(mapc 'org-delete-overlay org-occur-highlights)
(setq org-occur-highlights nil)
+ (setq org-occur-parameters nil)
(unless noremove
(remove-hook 'before-change-functions
'org-remove-occur-highlights 'local))))
;;;; Priorities
-(defvar org-priority-regexp ".*?\\(\\[#\\([A-Z]\\)\\] ?\\)"
+(defvar org-priority-regexp ".*?\\(\\[#\\([A-Z0-9]\\)\\] ?\\)"
"Regular expression matching the priority indicator.")
(defvar org-remove-priority-next-time nil)
(defun org-priority (&optional action)
"Change the priority of an item by ARG.
-ACTION can be set, up, or down."
+ACTION can be `set', `up', `down', or a character."
(interactive)
(setq action (or action 'set))
(let (current new news have remove)
have t)
(setq current org-default-priority))
(cond
- ((eq action 'set)
- (message "Priority A-%c, SPC to remove: " org-lowest-priority)
- (setq new (read-char-exclusive))
+ ((or (eq action 'set) (integerp action))
+ (if (integerp action)
+ (setq new action)
+ (message "Priority %c-%c, SPC to remove: " org-highest-priority org-lowest-priority)
+ (setq new (read-char-exclusive)))
+ (if (and (= (upcase org-highest-priority) org-highest-priority)
+ (= (upcase org-lowest-priority) org-lowest-priority))
+ (setq new (upcase new)))
(cond ((equal new ?\ ) (setq remove t))
- ((or (< (upcase new) ?A) (> (upcase new) org-lowest-priority))
+ ((or (< (upcase new) org-highest-priority) (> (upcase new) org-lowest-priority))
(error "Priority must be between `%c' and `%c'"
- ?A org-lowest-priority))))
+ org-highest-priority org-lowest-priority))))
((eq action 'up)
- (setq new (1- current)))
+ (if (and (not have) (eq last-command this-command))
+ (setq new org-lowest-priority)
+ (setq new (if (and org-priority-start-cycle-with-default (not have))
+ org-default-priority (1- current)))))
((eq action 'down)
- (setq new (1+ current)))
+ (if (and (not have) (eq last-command this-command))
+ (setq new org-highest-priority)
+ (setq new (if (and org-priority-start-cycle-with-default (not have))
+ org-default-priority (1+ current)))))
(t (error "Invalid action")))
- (setq new (min (max ?A (upcase new)) org-lowest-priority))
+ (if (or (< (upcase new) org-highest-priority)
+ (> (upcase new) org-lowest-priority))
+ (setq remove t))
(setq news (format "%c" new))
(if have
(if remove
(insert " [#" news "]"))
(goto-char (match-beginning 3))
(insert "[#" news "] ")))))
+ (org-preserve-lc (org-set-tags nil 'align))
(if remove
(message "Priority removed")
(message "Priority of current item set to %s" news))))
inclusion. When TODO-ONLY is non-nil, only lines with a TODO keyword
are included in the output."
(let* ((re (concat "[\n\r]" outline-regexp " *\\(\\<\\("
- (mapconcat 'regexp-quote
- (nreverse (cdr (reverse org-todo-keywords)))
- "\\|")
- "\\>\\)\\)? *\\(.*?\\)\\(:[A-Za-z_@0-9:]+:\\)?[ \t]*$"))
+ (mapconcat 'regexp-quote org-todo-keywords-1 "\\|")
+ (org-re
+ "\\>\\)\\)? *\\(.*?\\)\\(:[[:alnum:]_@:]+:\\)?[ \t]*$")))
(props (list 'face nil
'done-face 'org-done
'undone-face nil
'mouse-face 'highlight
'org-not-done-regexp org-not-done-regexp
+ 'org-todo-regexp org-todo-regexp
'keymap org-agenda-keymap
'help-echo
(format "mouse-2 or RET jump to org file %s"
- (abbreviate-file-name buffer-file-name))))
+ (abbreviate-file-name
+ (or (buffer-file-name (buffer-base-buffer))
+ (buffer-name (buffer-base-buffer)))))))
(case-fold-search nil)
lspos
tags tags-list tags-alist (llast 0) rtn level category i txt
- todo marker entry)
+ todo marker entry priority)
(save-excursion
(goto-char (point-min))
- (when (eq action 'sparse-tree) (org-overview))
+ (when (eq action 'sparse-tree)
+ (org-overview)
+ (org-remove-occur-highlights))
(while (re-search-forward re nil t)
(catch :skip
(setq todo (if (match-end 1) (match-string 2))
tags (if (match-end 4) (match-string 4)))
(goto-char (setq lspos (1+ (match-beginning 0))))
- (setq level (funcall outline-level)
+ (setq level (org-reduced-level (funcall outline-level))
category (org-get-category))
(setq i llast llast level)
;; remove tag lists from same and sublevels
(if org-use-tag-inheritance
(apply 'append (mapcar 'cdr tags-alist))
tags))
- (when (and (or (not todo-only) todo)
+ (when (and (or (not todo-only) (member todo org-not-done-keywords))
(eval matcher)
(or (not org-agenda-skip-archived-trees)
(not (member org-archive-tag tags-list))))
(and (eq action 'agenda) (org-agenda-skip))
;; list this headline
+
(if (eq action 'sparse-tree)
(progn
+ (and org-highlight-sparse-tree-matches
+ (org-get-heading) (match-end 0)
+ (org-highlight-new-match
+ (match-beginning 0) (match-beginning 1)))
(org-show-context 'tags-tree))
(setq txt (org-format-agenda-item
""
(if org-tags-match-list-sublevels
(make-string (1- level) ?.) "")
(org-get-heading))
- category tags-list))
+ category tags-list)
+ priority (org-get-priority txt))
(goto-char lspos)
(setq marker (org-agenda-new-marker))
(org-add-props txt props
- 'org-marker marker 'org-hd-marker marker 'org-category category)
+ 'org-marker marker 'org-hd-marker marker 'org-category category
+ 'priority priority 'type "tagsmatch")
(push txt rtn))
;; if we are to skip sublevels, jump to end of subtree
(or org-tags-match-list-sublevels (org-end-of-subtree t))))))
If optional argument TODO_ONLY is non-nil, only select lines that are
also TODO lines."
(interactive "P")
+ (org-prepare-agenda-buffers (list (current-buffer)))
(org-scan-tags 'sparse-tree (cdr (org-make-tags-matcher match)) todo-only))
+(defvar org-cached-props nil)
+(defun org-cached-entry-get (pom property)
+ (if (or (eq t org-use-property-inheritance)
+ (member property org-use-property-inheritance))
+ ;; Caching is not possible, check it directly
+ (org-entry-get pom property 'inherit)
+ ;; Get all properties, so that we can do complicated checks easily
+ (cdr (assoc property (or org-cached-props
+ (setq org-cached-props
+ (org-entry-properties pom)))))))
+
+(defun org-global-tags-completion-table (&optional files)
+ "Return the list of all tags in all agenda buffer/files."
+ (save-excursion
+ (org-uniquify
+ (delq nil
+ (apply 'append
+ (mapcar
+ (lambda (file)
+ (set-buffer (find-file-noselect file))
+ (append (org-get-buffer-tags)
+ (mapcar (lambda (x) (if (stringp (car-safe x))
+ (list (car-safe x)) nil))
+ org-tag-alist)))
+ (if (and files (car files))
+ files
+ (org-agenda-files))))))))
+
(defun org-make-tags-matcher (match)
"Create the TAGS//TODO matcher form for the selection string MATCH."
;; todo-only is scoped dynamically into this function, and the function
;; may change it it the matcher asksk for it.
(unless match
;; Get a new match request, with completion
- (setq org-last-tags-completion-table
- (or org-tag-alist
- org-last-tags-completion-table))
- (setq match (completing-read
- "Match: " 'org-tags-completion-function nil nil nil
- 'org-tags-history)))
+ (let ((org-last-tags-completion-table
+ (org-global-tags-completion-table)))
+ (setq match (completing-read
+ "Match: " 'org-tags-completion-function nil nil nil
+ 'org-tags-history))))
;; Parse the string and create a lisp form
(let ((match0 match)
- (re "^&?\\([-+:]\\)?\\({[^}]+}\\|LEVEL=\\([0-9]+\\)\\|[A-Za-z_@0-9]+\\)")
+ (re (org-re "^&?\\([-+:]\\)?\\({[^}]+}\\|LEVEL=\\([0-9]+\\)\\|\\([[:alnum:]_]+\\)=\\({[^}]+}\\|\"[^\"]*\"\\)\\|[[:alnum:]_@]+\\)"))
minus tag mm
tagsmatch todomatch tagsmatcher todomatcher kwd matcher
- orterms term orlist re-p level-p)
+ orterms term orlist re-p level-p prop-p pn pv cat-p gv)
(if (string-match "/+" match)
;; match contains also a todo-matching request
(progn
tag (match-string 2 term)
re-p (equal (string-to-char tag) ?{)
level-p (match-end 3)
+ prop-p (match-end 4)
mm (cond
(re-p `(org-match-any-p ,(substring tag 1 -1) tags-list))
(level-p `(= level ,(string-to-number
(match-string 3 term))))
+ (prop-p
+ (setq pn (match-string 4 term)
+ pv (match-string 5 term)
+ cat-p (equal pn "CATEGORY")
+ re-p (equal (string-to-char pv) ?{)
+ pv (substring pv 1 -1))
+ (if (equal pn "CATEGORY")
+ (setq gv '(get-text-property (point) 'org-category))
+ (setq gv `(org-cached-entry-get nil ,pn)))
+ (if re-p
+ `(string-match ,pv (or ,gv ""))
+ `(equal ,pv (or ,gv ""))))
(t `(member ,(downcase tag) tags-list)))
mm (if minus (list 'not mm) mm)
term (substring term (match-end 0)))
(car tagsmatcher))
orlist)
(setq tagsmatcher nil))
- (setq tagsmatcher (if (> (length orlist) 1) (cons 'or orlist) (car orlist))))
+ (setq tagsmatcher (if (> (length orlist) 1) (cons 'or orlist) (car orlist)))
+ (setq tagsmatcher
+ (list 'progn '(setq org-cached-props nil) tagsmatcher)))
;; Make the todo matcher
(if (or (not todomatch) (not (string-match "\\S-" todomatch)))
(defvar org-tags-overlay (org-make-overlay 1 1))
(org-detach-overlay org-tags-overlay)
+(defun org-align-tags-here (to-col)
+ ;; Assumes that this is a headline
+ (let ((pos (point)) (col (current-column)) tags)
+ (beginning-of-line 1)
+ (if (and (looking-at (org-re ".*?\\([ \t]+\\)\\(:[[:alnum:]_@:]+:\\)[ \t]*$"))
+ (< pos (match-beginning 2)))
+ (progn
+ (setq tags (match-string 2))
+ (goto-char (match-beginning 1))
+ (insert " ")
+ (delete-region (point) (1+ (match-end 0)))
+ (backward-char 1)
+ (move-to-column
+ (max (1+ (current-column))
+ (1+ col)
+ (if (> to-col 0)
+ to-col
+ (- (abs to-col) (length tags))))
+ t)
+ (insert tags)
+ (move-to-column (min (current-column) col) t))
+ (goto-char pos))))
+
(defun org-set-tags (&optional arg just-align)
"Set the tags for the current headline.
With prefix ARG, realign all tags in headings in the current buffer."
(interactive "P")
(let* ((re (concat "^" outline-regexp))
- (current (org-get-tags))
+ (current (org-get-tags-string))
+ (col (current-column))
+ (org-setting-tags t)
table current-tags inherited-tags ; computed below when needed
tags p0 c0 c1 rpl)
(if arg
(save-excursion
(goto-char (point-min))
- (let (buffer-invisibility-spec) ; Emacs 21 compatibility
+ (let ((buffer-invisibility-spec (org-inhibit-invisibility)))
(while (re-search-forward re nil t)
(org-set-tags nil t)
(end-of-line 1)))
(if (or (eq t org-use-fast-tag-selection)
(and org-use-fast-tag-selection
(delq nil (mapcar 'cdr table))))
- (org-fast-tag-selection current-tags inherited-tags table)
+ (org-fast-tag-selection
+ current-tags inherited-tags table
+ (if org-fast-tag-selection-include-todo org-todo-key-alist))
(let ((org-add-colon-after-tag-completion t))
(org-trim
- (completing-read "Tags: " 'org-tags-completion-function
- nil nil current 'org-tags-history))))))
+ (org-without-partial-completion
+ (completing-read "Tags: " 'org-tags-completion-function
+ nil nil current 'org-tags-history)))))))
(while (string-match "[-+&]+" tags)
;; No boolean logic, just a list
(setq tags (replace-match ":" t t tags))))
+
(if (string-match "\\`[\t ]*\\'" tags)
(setq tags "")
(unless (string-match ":$" tags) (setq tags (concat tags ":")))
;; Insert new tags at the correct column
(beginning-of-line 1)
- (if (re-search-forward
- (concat "\\([ \t]*" (regexp-quote current) "\\)[ \t]*$")
- (point-at-eol) t)
- (progn
- (if (equal tags "")
- (setq rpl "")
- (goto-char (match-beginning 0))
- (setq c0 (current-column) p0 (point)
- c1 (max (1+ c0) (if (> org-tags-column 0)
- org-tags-column
- (- (- org-tags-column) (length tags))))
- rpl (concat (make-string (max 0 (- c1 c0)) ?\ ) tags)))
- (replace-match rpl t t)
- (and (not (featurep 'xemacs)) c0 (tabify p0 (point)))
- tags)
- (error "Tags alignment failed")))))
+ (cond
+ ((and (equal current "") (equal tags "")))
+ ((re-search-forward
+ (concat "\\([ \t]*" (regexp-quote current) "\\)[ \t]*$")
+ (point-at-eol) t)
+ (if (equal tags "")
+ (setq rpl "")
+ (goto-char (match-beginning 0))
+ (setq c0 (current-column) p0 (point)
+ c1 (max (1+ c0) (if (> org-tags-column 0)
+ org-tags-column
+ (- (- org-tags-column) (length tags))))
+ rpl (concat (make-string (max 0 (- c1 c0)) ?\ ) tags)))
+ (replace-match rpl t t)
+ (and (not (featurep 'xemacs)) c0 indent-tabs-mode (tabify p0 (point)))
+ tags)
+ (t (error "Tags alignment failed")))
+ (move-to-column col)
+ (unless just-align
+ (run-hooks 'org-after-tags-change-hook)))))
+
+(defun org-change-tag-in-region (beg end tag off)
+ "Add or remove TAG for each entry in the region.
+This works in the agenda, and also in an org-mode buffer."
+ (interactive
+ (list (region-beginning) (region-end)
+ (let ((org-last-tags-completion-table
+ (if (org-mode-p)
+ (org-get-buffer-tags)
+ (org-global-tags-completion-table))))
+ (completing-read
+ "Tag: " 'org-tags-completion-function nil nil nil
+ 'org-tags-history))
+ (progn
+ (message "[s]et or [r]emove? ")
+ (equal (read-char-exclusive) ?r))))
+ (if (fboundp 'deactivate-mark) (deactivate-mark))
+ (let ((agendap (equal major-mode 'org-agenda-mode))
+ l1 l2 m buf pos newhead (cnt 0))
+ (goto-char end)
+ (setq l2 (1- (org-current-line)))
+ (goto-char beg)
+ (setq l1 (org-current-line))
+ (loop for l from l1 to l2 do
+ (goto-line l)
+ (setq m (get-text-property (point) 'org-hd-marker))
+ (when (or (and (org-mode-p) (org-on-heading-p))
+ (and agendap m))
+ (setq buf (if agendap (marker-buffer m) (current-buffer))
+ pos (if agendap m (point)))
+ (with-current-buffer buf
+ (save-excursion
+ (save-restriction
+ (goto-char pos)
+ (setq cnt (1+ cnt))
+ (org-toggle-tag tag (if off 'off 'on))
+ (setq newhead (org-get-heading)))))
+ (and agendap (org-agenda-change-all-lines newhead m))))
+ (message "Tag :%s: %s in %d headings" tag (if off "removed" "set") cnt)))
(defun org-tags-completion-function (string predicate &optional flag)
(let (s1 s2 rtn (ctable org-last-tags-completion-table)
;; try completion
(setq rtn (try-completion s2 ctable confirm))
(if (stringp rtn)
- (concat s1 s2 (substring rtn (length s2))
- (if (and org-add-colon-after-tag-completion
- (assoc rtn ctable))
- ":" "")))
- )
+ (setq rtn
+ (concat s1 s2 (substring rtn (length s2))
+ (if (and org-add-colon-after-tag-completion
+ (assoc rtn ctable))
+ ":" ""))))
+ rtn)
((eq flag t)
;; all-completions
(all-completions s2 ctable confirm)
(put-text-property 0 (length s) 'face '(secondary-selection org-tag) s)
(org-overlay-display org-tags-overlay (concat prefix s)))))
-(defun org-fast-tag-selection (current inherited table)
+(defun org-fast-tag-selection (current inherited table &optional todo-table)
"Fast tag selection with single keys.
CURRENT is the current list of tags in the headline, INHERITED is the
list of inherited tags, and TABLE is an alist of tags and corresponding keys,
-possibly with grouping information.
+possibly with grouping information. TODO-TABLE is a similar table with
+TODO keywords, should these have keys assigned to them.
If the keys are nil, a-z are automatically assigned.
Returns the new tags string, or nil to not change the current settings."
- (let* ((maxlen (apply 'max (mapcar
+ (let* ((fulltable (append table todo-table))
+ (maxlen (apply 'max (mapcar
(lambda (x)
(if (stringp (car x)) (string-width (car x)) 0))
- table)))
+ fulltable)))
(buf (current-buffer))
(expert (eq org-fast-tag-selection-single-key 'expert))
(buffer-tags nil)
(fwidth (+ maxlen 3 1 3))
(ncol (/ (- (window-width) 4) fwidth))
(i-face 'org-done)
- (c-face 'org-tag)
+ (c-face 'org-todo)
tg cnt e c char c1 c2 ntable tbl rtn
ov-start ov-end ov-prefix
(exit-after-next org-fast-tag-selection-single-key)
+ (done-keywords org-done-keywords)
groups ingroup)
(save-excursion
(beginning-of-line 1)
- (if (looking-at ".*[ \t]\\(:[A-Za-z_@0-9:]+:\\)[ \t]*\\(\r\\|$\\)")
+ (if (looking-at
+ (org-re ".*[ \t]\\(:[[:alnum:]_@:]+:\\)[ \t]*$"))
(setq ov-start (match-beginning 1)
ov-end (match-end 1)
ov-prefix "")
(set-buffer (get-buffer-create " *Org tags*"))
(delete-other-windows)
(split-window-vertically)
- (switch-to-buffer-other-window (get-buffer-create " *Org tags*")))
+ (org-switch-to-buffer-other-window (get-buffer-create " *Org tags*")))
(erase-buffer)
+ (org-set-local 'org-done-keywords done-keywords)
(org-fast-tag-insert "Inherited" inherited i-face "\n")
(org-fast-tag-insert "Current" current c-face "\n\n")
(org-fast-tag-show-exit exit-after-next)
(org-set-current-tags-overlay current ov-prefix)
- (setq tbl table char ?a cnt 0)
+ (setq tbl fulltable char ?a cnt 0)
(while (setq e (pop tbl))
(cond
((equal e '(:startgroup))
(if ingroup (push tg (car groups)))
(setq tg (org-add-props tg nil 'face
(cond
+ ((not (assoc tg table))
+ (org-get-todo-face tg))
((member tg current) c-face)
((member tg inherited) i-face)
(t nil))))
(setq expert nil)
(delete-other-windows)
(split-window-vertically)
- (switch-to-buffer-other-window " *Org tags*")
+ (org-switch-to-buffer-other-window " *Org tags*")
(and (fboundp 'fit-window-to-buffer)
(fit-window-to-buffer))))
((or (= c ?\C-g)
(setq current (delete tg current))
(push tg current)))
(if exit-after-next (setq exit-after-next 'now)))
+ ((setq e (rassoc c todo-table) tg (car e))
+ (with-current-buffer buf
+ (save-excursion (org-todo tg)))
+ (if exit-after-next (setq exit-after-next 'now)))
((setq e (rassoc c ntable) tg (car e))
(if (member tg current)
(setq current (delete tg current))
(loop for g in groups do
(if (member tg g)
- (mapcar (lambda (x)
- (setq current (delete x current)))
- g)))
+ (mapc (lambda (x)
+ (setq current (delete x current)))
+ g)))
(push tg current))
(if exit-after-next (setq exit-after-next 'now))))
(delete-region (point) (point-at-eol))
(org-fast-tag-insert "Current" current c-face)
(org-set-current-tags-overlay current ov-prefix)
- (while (re-search-forward "\\[.\\] \\([a-zA-Z0-9_@]+\\)" nil t)
+ (while (re-search-forward
+ (org-re "\\[.\\] \\([[:alnum:]_@]+\\)") nil t)
(setq tg (match-string 1))
- (add-text-properties (match-beginning 1) (match-end 1)
- (list 'face
- (cond
- ((member tg current) c-face)
- ((member tg inherited) i-face)
- (t nil)))))
+ (add-text-properties
+ (match-beginning 1) (match-end 1)
+ (list 'face
+ (cond
+ ((member tg current) c-face)
+ ((member tg inherited) i-face)
+ (t (get-text-property (match-beginning 1) 'face))))))
(goto-char (point-min)))))
(org-detach-overlay org-tags-overlay)
(if rtn
(mapconcat 'identity current ":")
nil))))
-(defun org-get-tags ()
+(defun org-get-tags-string ()
"Get the TAGS string in the current headline."
(unless (org-on-heading-p t)
(error "Not on a heading"))
(save-excursion
(beginning-of-line 1)
- (if (looking-at ".*[ \t]\\(:[A-Za-z_@0-9:]+:\\)[ \t]*\\(\r\\|$\\)")
+ (if (looking-at (org-re ".*[ \t]\\(:[[:alnum:]_@:]+:\\)[ \t]*$"))
(org-match-string-no-properties 1)
"")))
+(defun org-get-tags ()
+ "Get the list of tags specified in the current headline."
+ (org-split-string (org-get-tags-string) ":"))
+
(defun org-get-buffer-tags ()
"Get a table of all tags used in the buffer, for completion."
(let (tags)
(save-excursion
(goto-char (point-min))
- (while (re-search-forward "[ \t]:\\([A-Za-z_@0-9:]+\\):[ \t\r\n]" nil t)
- (mapc (lambda (x) (add-to-list 'tags x))
- (org-split-string (org-match-string-no-properties 1) ":"))))
+ (while (re-search-forward
+ (org-re "[ \t]:\\([[:alnum:]_@:]+\\):[ \t\r\n]") nil t)
+ (when (equal (char-after (point-at-bol 0)) ?*)
+ (mapc (lambda (x) (add-to-list 'tags x))
+ (org-split-string (org-match-string-no-properties 1) ":")))))
(mapcar 'list tags)))
+
+;;;; Properties
+
+;;; Setting and retrieving properties
+
+(defconst org-special-properties
+ '("TODO" "TAGS" "ALLTAGS" "DEADLINE" "SCHEDULED" "CLOCK" "PRIORITY"
+ "TIMESTAMP" "TIMESTAMP_IA")
+ "The special properties valid in Org-mode.
+
+These are properties that are not defined in the property drawer,
+but in some other way.")
+
+(defconst org-default-properties
+ '("ARCHIVE" "CATEGORY" "SUMMARY" "DESCRIPTION"
+ "LOCATION" "LOGGING" "COLUMNS")
+ "Some properties that are used by Org-mode for various purposes.
+Being in this list makes sure that they are offered for completion.")
+
+(defconst org-property-start-re "^[ \t]*:PROPERTIES:[ \t]*$"
+ "Regular expression matching the first line of a property drawer.")
+
+(defconst org-property-end-re "^[ \t]*:END:[ \t]*$"
+ "Regular expression matching the first line of a property drawer.")
+
+(defun org-property-action ()
+ "Do an action on properties."
+ (interactive)
+ (let (c)
+ (org-at-property-p)
+ (message "Property Action: [s]et [d]elete [D]elete globally [c]ompute")
+ (setq c (read-char-exclusive))
+ (cond
+ ((equal c ?s)
+ (call-interactively 'org-set-property))
+ ((equal c ?d)
+ (call-interactively 'org-delete-property))
+ ((equal c ?D)
+ (call-interactively 'org-delete-property-globally))
+ ((equal c ?c)
+ (call-interactively 'org-compute-property-at-point))
+ (t (error "No such property action %c" c)))))
+
+(defun org-at-property-p ()
+ "Is the cursor in a property line?"
+ ;; FIXME: Does not check if we are actually in the drawer.
+ ;; FIXME: also returns true on any drawers.....
+ ;; This is used by C-c C-c for property action.
+ (save-excursion
+ (beginning-of-line 1)
+ (looking-at (org-re "^[ \t]*\\(:\\([[:alpha:]][[:alnum:]_-]*\\):\\)[ \t]*\\(.*\\)"))))
+
+(defmacro org-with-point-at (pom &rest body)
+ "Move to buffer and point of point-or-marker POM for the duration of BODY."
+ (declare (indent 1) (debug t))
+ `(save-excursion
+ (if (markerp pom) (set-buffer (marker-buffer pom)))
+ (save-excursion
+ (goto-char (or pom (point)))
+ ,@body)))
+
+(defun org-get-property-block (&optional beg end force)
+ "Return the (beg . end) range of the body of the property drawer.
+BEG and END can be beginning and end of subtree, if not given
+they will be found.
+If the drawer does not exist and FORCE is non-nil, create the drawer."
+ (catch 'exit
+ (save-excursion
+ (let* ((beg (or beg (progn (org-back-to-heading t) (point))))
+ (end (or end (progn (outline-next-heading) (point)))))
+ (goto-char beg)
+ (if (re-search-forward org-property-start-re end t)
+ (setq beg (1+ (match-end 0)))
+ (if force
+ (save-excursion
+ (org-insert-property-drawer)
+ (setq end (progn (outline-next-heading) (point))))
+ (throw 'exit nil))
+ (goto-char beg)
+ (if (re-search-forward org-property-start-re end t)
+ (setq beg (1+ (match-end 0)))))
+ (if (re-search-forward org-property-end-re end t)
+ (setq end (match-beginning 0))
+ (or force (throw 'exit nil))
+ (goto-char beg)
+ (setq end beg)
+ (org-indent-line-function)
+ (insert ":END:\n"))
+ (cons beg end)))))
+
+(defun org-entry-properties (&optional pom which)
+ "Get all properties of the entry at point-or-marker POM.
+This includes the TODO keyword, the tags, time strings for deadline,
+scheduled, and clocking, and any additional properties defined in the
+entry. The return value is an alist, keys may occur multiple times
+if the property key was used several times.
+POM may also be nil, in which case the current entry is used.
+If WHICH is nil or `all', get all properties. If WHICH is
+`special' or `standard', only get that subclass."
+ (setq which (or which 'all))
+ (org-with-point-at pom
+ (let ((clockstr (substring org-clock-string 0 -1))
+ (excluded '("TODO" "TAGS" "ALLTAGS" "PRIORITY"))
+ beg end range props sum-props key value string clocksum)
+ (save-excursion
+ (when (condition-case nil (org-back-to-heading t) (error nil))
+ (setq beg (point))
+ (setq sum-props (get-text-property (point) 'org-summaries))
+ (setq clocksum (get-text-property (point) :org-clock-minutes))
+ (outline-next-heading)
+ (setq end (point))
+ (when (memq which '(all special))
+ ;; Get the special properties, like TODO and tags
+ (goto-char beg)
+ (when (and (looking-at org-todo-line-regexp) (match-end 2))
+ (push (cons "TODO" (org-match-string-no-properties 2)) props))
+ (when (looking-at org-priority-regexp)
+ (push (cons "PRIORITY" (org-match-string-no-properties 2)) props))
+ (when (and (setq value (org-get-tags-string))
+ (string-match "\\S-" value))
+ (push (cons "TAGS" value) props))
+ (when (setq value (org-get-tags-at))
+ (push (cons "ALLTAGS" (concat ":" (mapconcat 'identity value ":") ":"))
+ props))
+ (while (re-search-forward org-maybe-keyword-time-regexp end t)
+ (setq key (if (match-end 1) (substring (org-match-string-no-properties 1) 0 -1))
+ string (if (equal key clockstr)
+ (org-no-properties
+ (org-trim
+ (buffer-substring
+ (match-beginning 3) (goto-char (point-at-eol)))))
+ (substring (org-match-string-no-properties 3) 1 -1)))
+ (unless key
+ (if (= (char-after (match-beginning 3)) ?\[)
+ (setq key "TIMESTAMP_IA")
+ (setq key "TIMESTAMP")))
+ (when (or (equal key clockstr) (not (assoc key props)))
+ (push (cons key string) props)))
+
+ )
+
+ (when (memq which '(all standard))
+ ;; Get the standard properties, like :PORP: ...
+ (setq range (org-get-property-block beg end))
+ (when range
+ (goto-char (car range))
+ (while (re-search-forward
+ (org-re "^[ \t]*:\\([[:alpha:]][[:alnum:]_-]*\\):[ \t]*\\(\\S-.*\\)?")
+ (cdr range) t)
+ (setq key (org-match-string-no-properties 1)
+ value (org-trim (or (org-match-string-no-properties 2) "")))
+ (unless (member key excluded)
+ (push (cons key (or value "")) props)))))
+ (if clocksum
+ (push (cons "CLOCKSUM"
+ (org-column-number-to-string (/ (float clocksum) 60.)
+ 'add_times))
+ props))
+ (append sum-props (nreverse props)))))))
+
+(defun org-entry-get (pom property &optional inherit)
+ "Get value of PROPERTY for entry at point-or-marker POM.
+If INHERIT is non-nil and the entry does not have the property,
+then also check higher levels of the hierarchy.
+If the property is present but empty, the return value is the empty string.
+If the property is not present at all, nil is returned."
+ (org-with-point-at pom
+ (if inherit
+ (org-entry-get-with-inheritance property)
+ (if (member property org-special-properties)
+ ;; We need a special property. Use brute force, get all properties.
+ (cdr (assoc property (org-entry-properties nil 'special)))
+ (let ((range (org-get-property-block)))
+ (if (and range
+ (goto-char (car range))
+ (re-search-forward
+ (concat "^[ \t]*:" property ":[ \t]*\\(.*\\S-\\)?")
+ (cdr range) t))
+ ;; Found the property, return it.
+ (if (match-end 1)
+ (org-match-string-no-properties 1)
+ "")))))))
+
+(defun org-entry-delete (pom property)
+ "Delete the property PROPERTY from entry at point-or-marker POM."
+ (org-with-point-at pom
+ (if (member property org-special-properties)
+ nil ; cannot delete these properties.
+ (let ((range (org-get-property-block)))
+ (if (and range
+ (goto-char (car range))
+ (re-search-forward
+ (concat "^[ \t]*:" property ":[ \t]*\\(.*\\S-\\)")
+ (cdr range) t))
+ (progn
+ (delete-region (match-beginning 0) (1+ (point-at-eol)))
+ t)
+ nil)))))
+
+;; Multi-values properties are properties that contain multiple values
+;; These values are assumed to be single words, separated by whitespace.
+(defun org-entry-add-to-multivalued-property (pom property value)
+ "Add VALUE to the words in the PROPERTY in entry at point-or-marker POM."
+ (let* ((old (org-entry-get pom property))
+ (values (and old (org-split-string old "[ \t]"))))
+ (unless (member value values)
+ (setq values (cons value values))
+ (org-entry-put pom property
+ (mapconcat 'identity values " ")))))
+
+(defun org-entry-remove-from-multivalued-property (pom property value)
+ "Remove VALUE from words in the PROPERTY in entry at point-or-marker POM."
+ (let* ((old (org-entry-get pom property))
+ (values (and old (org-split-string old "[ \t]"))))
+ (when (member value values)
+ (setq values (delete value values))
+ (org-entry-put pom property
+ (mapconcat 'identity values " ")))))
+
+(defun org-entry-member-in-multivalued-property (pom property value)
+ "Is VALUE one of the words in the PROPERTY in entry at point-or-marker POM?"
+ (let* ((old (org-entry-get pom property))
+ (values (and old (org-split-string old "[ \t]"))))
+ (member value values)))
+
+(defvar org-entry-property-inherited-from (make-marker))
+
+(defun org-entry-get-with-inheritance (property)
+ "Get entry property, and search higher levels if not present."
+ (let (tmp)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (catch 'ex
+ (while t
+ (when (setq tmp (org-entry-get nil property))
+ (org-back-to-heading t)
+ (move-marker org-entry-property-inherited-from (point))
+ (throw 'ex tmp))
+ (or (org-up-heading-safe) (throw 'ex nil)))))
+ (or tmp (cdr (assoc property org-local-properties))
+ (cdr (assoc property org-global-properties))))))
+
+(defun org-entry-put (pom property value)
+ "Set PROPERTY to VALUE for entry at point-or-marker POM."
+ (org-with-point-at pom
+ (org-back-to-heading t)
+ (let ((beg (point)) (end (save-excursion (outline-next-heading) (point)))
+ range)
+ (cond
+ ((equal property "TODO")
+ (when (and (stringp value) (string-match "\\S-" value)
+ (not (member value org-todo-keywords-1)))
+ (error "\"%s\" is not a valid TODO state" value))
+ (if (or (not value)
+ (not (string-match "\\S-" value)))
+ (setq value 'none))
+ (org-todo value)
+ (org-set-tags nil 'align))
+ ((equal property "PRIORITY")
+ (org-priority (if (and value (stringp value) (string-match "\\S-" value))
+ (string-to-char value) ?\ ))
+ (org-set-tags nil 'align))
+ ((equal property "SCHEDULED")
+ (if (re-search-forward org-scheduled-time-regexp end t)
+ (cond
+ ((eq value 'earlier) (org-timestamp-change -1 'day))
+ ((eq value 'later) (org-timestamp-change 1 'day))
+ (t (call-interactively 'org-schedule)))
+ (call-interactively 'org-schedule)))
+ ((equal property "DEADLINE")
+ (if (re-search-forward org-deadline-time-regexp end t)
+ (cond
+ ((eq value 'earlier) (org-timestamp-change -1 'day))
+ ((eq value 'later) (org-timestamp-change 1 'day))
+ (t (call-interactively 'org-deadline)))
+ (call-interactively 'org-deadline)))
+ ((member property org-special-properties)
+ (error "The %s property can not yet be set with `org-entry-put'"
+ property))
+ (t ; a non-special property
+ (let ((buffer-invisibility-spec (org-inhibit-invisibility))) ; Emacs 21
+ (setq range (org-get-property-block beg end 'force))
+ (goto-char (car range))
+ (if (re-search-forward
+ (concat "^[ \t]*:" property ":\\(.*\\)") (cdr range) t)
+ (progn
+ (delete-region (match-beginning 1) (match-end 1))
+ (goto-char (match-beginning 1)))
+ (goto-char (cdr range))
+ (insert "\n")
+ (backward-char 1)
+ (org-indent-line-function)
+ (insert ":" property ":"))
+ (and value (insert " " value))
+ (org-indent-line-function)))))))
+
+(defun org-buffer-property-keys (&optional include-specials include-defaults include-columns)
+ "Get all property keys in the current buffer.
+With INCLUDE-SPECIALS, also list the special properties that relect things
+like tags and TODO state.
+With INCLUDE-DEFAULTS, also include properties that has special meaning
+internally: ARCHIVE, CATEGORY, SUMMARY, DESCRIPTION, LOCATION, and LOGGING.
+With INCLUDE-COLUMNS, also include property names given in COLUMN
+formats in the current buffer."
+ (let (rtn range cfmt cols s p)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (while (re-search-forward org-property-start-re nil t)
+ (setq range (org-get-property-block))
+ (goto-char (car range))
+ (while (re-search-forward
+ (org-re "^[ \t]*:\\([-[:alnum:]_]+\\):")
+ (cdr range) t)
+ (add-to-list 'rtn (org-match-string-no-properties 1)))
+ (outline-next-heading))))
+
+ (when include-specials
+ (setq rtn (append org-special-properties rtn)))
+
+ (when include-defaults
+ (mapc (lambda (x) (add-to-list 'rtn x)) org-default-properties))
+
+ (when include-columns
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (while (re-search-forward
+ "^\\(#\\+COLUMNS:\\|[ \t]*:COLUMNS:\\)[ \t]*\\(.*\\)"
+ nil t)
+ (setq cfmt (match-string 2) s 0)
+ (while (string-match (org-re "%[0-9]*\\([-[:alnum:]_]+\\)")
+ cfmt s)
+ (setq s (match-end 0)
+ p (match-string 1 cfmt))
+ (unless (or (equal p "ITEM")
+ (member p org-special-properties))
+ (add-to-list 'rtn (match-string 1 cfmt))))))))
+
+ (sort rtn (lambda (a b) (string< (upcase a) (upcase b))))))
+
+(defun org-property-values (key)
+ "Return a list of all values of property KEY."
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (let ((re (concat "^[ \t]*:" key ":[ \t]*\\(\\S-.*\\)"))
+ values)
+ (while (re-search-forward re nil t)
+ (add-to-list 'values (org-trim (match-string 1))))
+ (delete "" values)))))
+
+(defun org-insert-property-drawer ()
+ "Insert a property drawer into the current entry."
+ (interactive)
+ (org-back-to-heading t)
+ (looking-at outline-regexp)
+ (let ((indent (- (match-end 0)(match-beginning 0)))
+ (beg (point))
+ (re (concat "^[ \t]*" org-keyword-time-regexp))
+ end hiddenp)
+ (outline-next-heading)
+ (setq end (point))
+ (goto-char beg)
+ (while (re-search-forward re end t))
+ (setq hiddenp (org-invisible-p))
+ (end-of-line 1)
+ (and (equal (char-after) ?\n) (forward-char 1))
+ (org-skip-over-state-notes)
+ (skip-chars-backward " \t\n\r")
+ (if (eq (char-before) ?*) (forward-char 1))
+ (let ((inhibit-read-only t)) (insert "\n:PROPERTIES:\n:END:"))
+ (beginning-of-line 0)
+ (indent-to-column indent)
+ (beginning-of-line 2)
+ (indent-to-column indent)
+ (beginning-of-line 0)
+ (if hiddenp
+ (save-excursion
+ (org-back-to-heading t)
+ (hide-entry))
+ (org-flag-drawer t))))
+
+(defun org-set-property (property value)
+ "In the current entry, set PROPERTY to VALUE.
+When called interactively, this will prompt for a property name, offering
+completion on existing and default properties. And then it will prompt
+for a value, offering competion either on allowed values (via an inherited
+xxx_ALL property) or on existing values in other instances of this property
+in the current file."
+ (interactive
+ (let* ((prop (completing-read
+ "Property: " (mapcar 'list (org-buffer-property-keys nil t t))))
+ (cur (org-entry-get nil prop))
+ (allowed (org-property-get-allowed-values nil prop 'table))
+ (existing (mapcar 'list (org-property-values prop)))
+ (val (if allowed
+ (completing-read "Value: " allowed nil 'req-match)
+ (completing-read
+ (concat "Value" (if (and cur (string-match "\\S-" cur))
+ (concat "[" cur "]") "")
+ ": ")
+ existing nil nil "" nil cur))))
+ (list prop (if (equal val "") cur val))))
+ (unless (equal (org-entry-get nil property) value)
+ (org-entry-put nil property value)))
+
+(defun org-delete-property (property)
+ "In the current entry, delete PROPERTY."
+ (interactive
+ (let* ((prop (completing-read
+ "Property: " (org-entry-properties nil 'standard))))
+ (list prop)))
+ (message "Property %s %s" property
+ (if (org-entry-delete nil property)
+ "deleted"
+ "was not present in the entry")))
+
+(defun org-delete-property-globally (property)
+ "Remove PROPERTY globally, from all entries."
+ (interactive
+ (let* ((prop (completing-read
+ "Globally remove property: "
+ (mapcar 'list (org-buffer-property-keys)))))
+ (list prop)))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (let ((cnt 0))
+ (while (re-search-forward
+ (concat "^[ \t]*:" (regexp-quote property) ":.*\n?")
+ nil t)
+ (setq cnt (1+ cnt))
+ (replace-match ""))
+ (message "Property \"%s\" removed from %d entries" property cnt)))))
+
+(defvar org-columns-current-fmt-compiled) ; defined below
+
+(defun org-compute-property-at-point ()
+ "Compute the property at point.
+This looks for an enclosing column format, extracts the operator and
+then applies it to the proerty in the column format's scope."
+ (interactive)
+ (unless (org-at-property-p)
+ (error "Not at a property"))
+ (let ((prop (org-match-string-no-properties 2)))
+ (org-columns-get-format-and-top-level)
+ (unless (nth 3 (assoc prop org-columns-current-fmt-compiled))
+ (error "No operator defined for property %s" prop))
+ (org-columns-compute prop)))
+
+(defun org-property-get-allowed-values (pom property &optional table)
+ "Get allowed values for the property PROPERTY.
+When TABLE is non-nil, return an alist that can directly be used for
+completion."
+ (let (vals)
+ (cond
+ ((equal property "TODO")
+ (setq vals (org-with-point-at pom
+ (append org-todo-keywords-1 '("")))))
+ ((equal property "PRIORITY")
+ (let ((n org-lowest-priority))
+ (while (>= n org-highest-priority)
+ (push (char-to-string n) vals)
+ (setq n (1- n)))))
+ ((member property org-special-properties))
+ (t
+ (setq vals (org-entry-get pom (concat property "_ALL") 'inherit))
+
+ (when (and vals (string-match "\\S-" vals))
+ (setq vals (car (read-from-string (concat "(" vals ")"))))
+ (setq vals (mapcar (lambda (x)
+ (cond ((stringp x) x)
+ ((numberp x) (number-to-string x))
+ ((symbolp x) (symbol-name x))
+ (t "???")))
+ vals)))))
+ (if table (mapcar 'list vals) vals)))
+
+(defun org-property-previous-allowed-value (&optional previous)
+ "Switch to the next allowed value for this property."
+ (interactive)
+ (org-property-next-allowed-value t))
+
+(defun org-property-next-allowed-value (&optional previous)
+ "Switch to the next allowed value for this property."
+ (interactive)
+ (unless (org-at-property-p)
+ (error "Not at a property"))
+ (let* ((key (match-string 2))
+ (value (match-string 3))
+ (allowed (or (org-property-get-allowed-values (point) key)
+ (and (member value '("[ ]" "[-]" "[X]"))
+ '("[ ]" "[X]"))))
+ nval)
+ (unless allowed
+ (error "Allowed values for this property have not been defined"))
+ (if previous (setq allowed (reverse allowed)))
+ (if (member value allowed)
+ (setq nval (car (cdr (member value allowed)))))
+ (setq nval (or nval (car allowed)))
+ (if (equal nval value)
+ (error "Only one allowed value for this property"))
+ (org-at-property-p)
+ (replace-match (concat " :" key ": " nval) t t)
+ (org-indent-line-function)
+ (beginning-of-line 1)
+ (skip-chars-forward " \t")))
+
+(defun org-find-entry-with-id (ident)
+ "Locate the entry that contains the ID property with exact value IDENT.
+IDENT can be a string, a symbol or a number, this function will search for
+the string representation of it.
+Return the position where this entry starts, or nil if there is no such entry."
+ (let ((id (cond
+ ((stringp ident) ident)
+ ((symbol-name ident) (symbol-name ident))
+ ((numberp ident) (number-to-string ident))
+ (t (error "IDENT %s must be a string, symbol or number" ident))))
+ (case-fold-search nil))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (when (re-search-forward
+ (concat "^[ \t]*:ID:[ \t]+" (regexp-quote id) "[ \t]*$")
+ nil t)
+ (org-back-to-heading)
+ (point))))))
+
+;;; Column View
+
+(defvar org-columns-overlays nil
+ "Holds the list of current column overlays.")
+
+(defvar org-columns-current-fmt nil
+ "Local variable, holds the currently active column format.")
+(defvar org-columns-current-fmt-compiled nil
+ "Local variable, holds the currently active column format.
+This is the compiled version of the format.")
+(defvar org-columns-current-widths nil
+ "Loval variable, holds the currently widths of fields.")
+(defvar org-columns-current-maxwidths nil
+ "Loval variable, holds the currently active maximum column widths.")
+(defvar org-columns-begin-marker (make-marker)
+ "Points to the position where last a column creation command was called.")
+(defvar org-columns-top-level-marker (make-marker)
+ "Points to the position where current columns region starts.")
+
+(defvar org-columns-map (make-sparse-keymap)
+ "The keymap valid in column display.")
+
+(defun org-columns-content ()
+ "Switch to contents view while in columns view."
+ (interactive)
+ (org-overview)
+ (org-content))
+
+(org-defkey org-columns-map "c" 'org-columns-content)
+(org-defkey org-columns-map "o" 'org-overview)
+(org-defkey org-columns-map "e" 'org-columns-edit-value)
+(org-defkey org-columns-map "\C-c\C-t" 'org-columns-todo)
+(org-defkey org-columns-map "\C-c\C-c" 'org-columns-set-tags-or-toggle)
+(org-defkey org-columns-map "\C-c\C-o" 'org-columns-open-link)
+(org-defkey org-columns-map "v" 'org-columns-show-value)
+(org-defkey org-columns-map "q" 'org-columns-quit)
+(org-defkey org-columns-map "r" 'org-columns-redo)
+(org-defkey org-columns-map "g" 'org-columns-redo)
+(org-defkey org-columns-map [left] 'backward-char)
+(org-defkey org-columns-map "\M-b" 'backward-char)
+(org-defkey org-columns-map "a" 'org-columns-edit-allowed)
+(org-defkey org-columns-map "s" 'org-columns-edit-attributes)
+(org-defkey org-columns-map "\M-f" (lambda () (interactive) (goto-char (1+ (point)))))
+(org-defkey org-columns-map [right] (lambda () (interactive) (goto-char (1+ (point)))))
+(org-defkey org-columns-map [(shift right)] 'org-columns-next-allowed-value)
+(org-defkey org-columns-map "n" 'org-columns-next-allowed-value)
+(org-defkey org-columns-map [(shift left)] 'org-columns-previous-allowed-value)
+(org-defkey org-columns-map "p" 'org-columns-previous-allowed-value)
+(org-defkey org-columns-map "<" 'org-columns-narrow)
+(org-defkey org-columns-map ">" 'org-columns-widen)
+(org-defkey org-columns-map [(meta right)] 'org-columns-move-right)
+(org-defkey org-columns-map [(meta left)] 'org-columns-move-left)
+(org-defkey org-columns-map [(shift meta right)] 'org-columns-new)
+(org-defkey org-columns-map [(shift meta left)] 'org-columns-delete)
+
+(easy-menu-define org-columns-menu org-columns-map "Org Column Menu"
+ '("Column"
+ ["Edit property" org-columns-edit-value t]
+ ["Next allowed value" org-columns-next-allowed-value t]
+ ["Previous allowed value" org-columns-previous-allowed-value t]
+ ["Show full value" org-columns-show-value t]
+ ["Edit allowed values" org-columns-edit-allowed t]
+ "--"
+ ["Edit column attributes" org-columns-edit-attributes t]
+ ["Increase column width" org-columns-widen t]
+ ["Decrease column width" org-columns-narrow t]
+ "--"
+ ["Move column right" org-columns-move-right t]
+ ["Move column left" org-columns-move-left t]
+ ["Add column" org-columns-new t]
+ ["Delete column" org-columns-delete t]
+ "--"
+ ["CONTENTS" org-columns-content t]
+ ["OVERVIEW" org-overview t]
+ ["Refresh columns display" org-columns-redo t]
+ "--"
+ ["Open link" org-columns-open-link t]
+ "--"
+ ["Quit" org-columns-quit t]))
+
+(defun org-columns-new-overlay (beg end &optional string face)
+ "Create a new column overlay and add it to the list."
+ (let ((ov (org-make-overlay beg end)))
+ (org-overlay-put ov 'face (or face 'secondary-selection))
+ (org-overlay-display ov string face)
+ (push ov org-columns-overlays)
+ ov))
+
+(defun org-columns-display-here (&optional props)
+ "Overlay the current line with column display."
+ (interactive)
+ (let* ((fmt org-columns-current-fmt-compiled)
+ (beg (point-at-bol))
+ (level-face (save-excursion
+ (beginning-of-line 1)
+ (and (looking-at "\\(\\**\\)\\(\\* \\)")
+ (org-get-level-face 2))))
+ (color (list :foreground
+ (face-attribute (or level-face 'default) :foreground)))
+ props pom property ass width f string ov column val modval)
+ ;; Check if the entry is in another buffer.
+ (unless props
+ (if (eq major-mode 'org-agenda-mode)
+ (setq pom (or (get-text-property (point) 'org-hd-marker)
+ (get-text-property (point) 'org-marker))
+ props (if pom (org-entry-properties pom) nil))
+ (setq props (org-entry-properties nil))))
+ ;; Walk the format
+ (while (setq column (pop fmt))
+ (setq property (car column)
+ ass (if (equal property "ITEM")
+ (cons "ITEM"
+ (save-match-data
+ (org-no-properties
+ (org-remove-tabs
+ (buffer-substring-no-properties
+ (point-at-bol) (point-at-eol))))))
+ (assoc property props))
+ width (or (cdr (assoc property org-columns-current-maxwidths))
+ (nth 2 column)
+ (length property))
+ f (format "%%-%d.%ds | " width width)
+ val (or (cdr ass) "")
+ modval (if (equal property "ITEM")
+ (org-columns-cleanup-item val org-columns-current-fmt-compiled))
+ string (format f (or modval val)))
+ ;; Create the overlay
+ (org-unmodified
+ (setq ov (org-columns-new-overlay
+ beg (setq beg (1+ beg)) string
+ (list color 'org-column)))
+;;; (list (get-text-property (point-at-bol) 'face) 'org-column)))
+ (org-overlay-put ov 'keymap org-columns-map)
+ (org-overlay-put ov 'org-columns-key property)
+ (org-overlay-put ov 'org-columns-value (cdr ass))
+ (org-overlay-put ov 'org-columns-value-modified modval)
+ (org-overlay-put ov 'org-columns-pom pom)
+ (org-overlay-put ov 'org-columns-format f))
+ (if (or (not (char-after beg))
+ (equal (char-after beg) ?\n))
+ (let ((inhibit-read-only t))
+ (save-excursion
+ (goto-char beg)
+ (org-unmodified (insert " ")))))) ;; FIXME: add props and remove later?
+ ;; Make the rest of the line disappear.
+ (org-unmodified
+ (setq ov (org-columns-new-overlay beg (point-at-eol)))
+ (org-overlay-put ov 'invisible t)
+ (org-overlay-put ov 'keymap org-columns-map)
+ (org-overlay-put ov 'intangible t)
+ (push ov org-columns-overlays)
+ (setq ov (org-make-overlay (1- (point-at-eol)) (1+ (point-at-eol))))
+ (org-overlay-put ov 'keymap org-columns-map)
+ (push ov org-columns-overlays)
+ (let ((inhibit-read-only t))
+ (put-text-property (max (point-min) (1- (point-at-bol)))
+ (min (point-max) (1+ (point-at-eol)))
+ 'read-only "Type `e' to edit property")))))
+
+(defvar org-previous-header-line-format nil
+ "The header line format before column view was turned on.")
+(defvar org-columns-inhibit-recalculation nil
+ "Inhibit recomputing of columns on column view startup.")
+
+
+(defvar header-line-format)
+(defun org-columns-display-here-title ()
+ "Overlay the newline before the current line with the table title."
+ (interactive)
+ (let ((fmt org-columns-current-fmt-compiled)
+ string (title "")
+ property width f column str widths)
+ (while (setq column (pop fmt))
+ (setq property (car column)
+ str (or (nth 1 column) property)
+ width (or (cdr (assoc property org-columns-current-maxwidths))
+ (nth 2 column)
+ (length str))
+ widths (push width widths)
+ f (format "%%-%d.%ds | " width width)
+ string (format f str)
+ title (concat title string)))
+ (setq title (concat
+ (org-add-props " " nil 'display '(space :align-to 0))
+ (org-add-props title nil 'face '(:weight bold :underline t))))
+ (org-set-local 'org-previous-header-line-format header-line-format)
+ (org-set-local 'org-columns-current-widths (nreverse widths))
+ (setq header-line-format title)))
+
+(defun org-columns-remove-overlays ()
+ "Remove all currently active column overlays."
+ (interactive)
+ (when (marker-buffer org-columns-begin-marker)
+ (with-current-buffer (marker-buffer org-columns-begin-marker)
+ (when (local-variable-p 'org-previous-header-line-format)
+ (setq header-line-format org-previous-header-line-format)
+ (kill-local-variable 'org-previous-header-line-format))
+ (move-marker org-columns-begin-marker nil)
+ (move-marker org-columns-top-level-marker nil)
+ (org-unmodified
+ (mapc 'org-delete-overlay org-columns-overlays)
+ (setq org-columns-overlays nil)
+ (let ((inhibit-read-only t))
+ (remove-text-properties (point-min) (point-max) '(read-only t)))))))
+
+(defun org-columns-cleanup-item (item fmt)
+ "Remove from ITEM what is a column in the format FMT."
+ (if (not org-complex-heading-regexp)
+ item
+ (when (string-match org-complex-heading-regexp item)
+ (concat
+ (org-add-props (concat (match-string 1 item) " ") nil
+ 'org-whitespace (* 2 (1- (org-reduced-level (- (match-end 1) (match-beginning 1))))))
+ (and (match-end 2) (not (assoc "TODO" fmt)) (concat " " (match-string 2 item)))
+ (and (match-end 3) (not (assoc "PRIORITY" fmt)) (concat " " (match-string 3 item)))
+ " " (match-string 4 item)
+ (and (match-end 5) (not (assoc "TAGS" fmt)) (concat " " (match-string 5 item)))))))
+
+(defun org-columns-show-value ()
+ "Show the full value of the property."
+ (interactive)
+ (let ((value (get-char-property (point) 'org-columns-value)))
+ (message "Value is: %s" (or value ""))))
+
+(defun org-columns-quit ()
+ "Remove the column overlays and in this way exit column editing."
+ (interactive)
+ (org-unmodified
+ (org-columns-remove-overlays)
+ (let ((inhibit-read-only t))
+ (remove-text-properties (point-min) (point-max) '(read-only t))))
+ (when (eq major-mode 'org-agenda-mode)
+ (message
+ "Modification not yet reflected in Agenda buffer, use `r' to refresh")))
+
+(defun org-columns-check-computed ()
+ "Check if this column value is computed.
+If yes, throw an error indicating that changing it does not make sense."
+ (let ((val (get-char-property (point) 'org-columns-value)))
+ (when (and (stringp val)
+ (get-char-property 0 'org-computed val))
+ (error "This value is computed from the entry's children"))))
+
+(defun org-columns-todo (&optional arg)
+ "Change the TODO state during column view."
+ (interactive "P")
+ (org-columns-edit-value "TODO"))
+
+(defun org-columns-set-tags-or-toggle (&optional arg)
+ "Toggle checkbox at point, or set tags for current headline."
+ (interactive "P")
+ (if (string-match "\\`\\[[ xX-]\\]\\'"
+ (get-char-property (point) 'org-columns-value))
+ (org-columns-next-allowed-value)
+ (org-columns-edit-value "TAGS")))
+
+(defun org-columns-edit-value (&optional key)
+ "Edit the value of the property at point in column view.
+Where possible, use the standard interface for changing this line."
+ (interactive)
+ (org-columns-check-computed)
+ (let* ((external-key key)
+ (col (current-column))
+ (key (or key (get-char-property (point) 'org-columns-key)))
+ (value (get-char-property (point) 'org-columns-value))
+ (bol (point-at-bol)) (eol (point-at-eol))
+ (pom (or (get-text-property bol 'org-hd-marker)
+ (point))) ; keep despite of compiler waring
+ (line-overlays
+ (delq nil (mapcar (lambda (x)
+ (and (eq (overlay-buffer x) (current-buffer))
+ (>= (overlay-start x) bol)
+ (<= (overlay-start x) eol)
+ x))
+ org-columns-overlays)))
+ nval eval allowed)
+ (cond
+ ((equal key "CLOCKSUM")
+ (error "This special column cannot be edited"))
+ ((equal key "ITEM")
+ (setq eval '(org-with-point-at pom
+ (org-edit-headline))))
+ ((equal key "TODO")
+ (setq eval '(org-with-point-at pom
+ (let ((current-prefix-arg
+ (if external-key current-prefix-arg '(4))))
+ (call-interactively 'org-todo)))))
+ ((equal key "PRIORITY")
+ (setq eval '(org-with-point-at pom
+ (call-interactively 'org-priority))))
+ ((equal key "TAGS")
+ (setq eval '(org-with-point-at pom
+ (let ((org-fast-tag-selection-single-key
+ (if (eq org-fast-tag-selection-single-key 'expert)
+ t org-fast-tag-selection-single-key)))
+ (call-interactively 'org-set-tags)))))
+ ((equal key "DEADLINE")
+ (setq eval '(org-with-point-at pom
+ (call-interactively 'org-deadline))))
+ ((equal key "SCHEDULED")
+ (setq eval '(org-with-point-at pom
+ (call-interactively 'org-schedule))))
+ (t
+ (setq allowed (org-property-get-allowed-values pom key 'table))
+ (if allowed
+ (setq nval (completing-read "Value: " allowed nil t))
+ (setq nval (read-string "Edit: " value)))
+ (setq nval (org-trim nval))
+ (when (not (equal nval value))
+ (setq eval '(org-entry-put pom key nval)))))
+ (when eval
+ (let ((inhibit-read-only t))
+ (remove-text-properties (max (point-min) (1- bol)) eol '(read-only t))
+ (unwind-protect
+ (progn
+ (setq org-columns-overlays
+ (org-delete-all line-overlays org-columns-overlays))
+ (mapc 'org-delete-overlay line-overlays)
+ (org-columns-eval eval))
+ (org-columns-display-here))))
+ (move-to-column col)
+ (if (and (org-mode-p)
+ (nth 3 (assoc key org-columns-current-fmt-compiled)))
+ (org-columns-update key))))
+
+(defun org-edit-headline () ; FIXME: this is not columns specific
+ "Edit the current headline, the part without TODO keyword, TAGS."
+ (org-back-to-heading)
+ (when (looking-at org-todo-line-regexp)
+ (let ((pre (buffer-substring (match-beginning 0) (match-beginning 3)))
+ (txt (match-string 3))
+ (post "")
+ txt2)
+ (if (string-match (org-re "[ \t]+:[[:alnum:]:_@]+:[ \t]*$") txt)
+ (setq post (match-string 0 txt)
+ txt (substring txt 0 (match-beginning 0))))
+ (setq txt2 (read-string "Edit: " txt))
+ (when (not (equal txt txt2))
+ (beginning-of-line 1)
+ (insert pre txt2 post)
+ (delete-region (point) (point-at-eol))
+ (org-set-tags nil t)))))
+
+(defun org-columns-edit-allowed ()
+ "Edit the list of allowed values for the current property."
+ (interactive)
+ (let* ((key (get-char-property (point) 'org-columns-key))
+ (key1 (concat key "_ALL"))
+ (allowed (org-entry-get (point) key1 t))
+ nval)
+ ;; FIXME: Cover editing TODO, TAGS etc in-buffer settings.????
+ (setq nval (read-string "Allowed: " allowed))
+ (org-entry-put
+ (cond ((marker-position org-entry-property-inherited-from)
+ org-entry-property-inherited-from)
+ ((marker-position org-columns-top-level-marker)
+ org-columns-top-level-marker))
+ key1 nval)))
+
+(defmacro org-no-warnings (&rest body)
+ (cons (if (fboundp 'with-no-warnings) 'with-no-warnings 'progn) body))
+
+(defun org-columns-eval (form)
+ (let (hidep)
+ (save-excursion
+ (beginning-of-line 1)
+ ;; `next-line' is needed here, because it skips invisible line.
+ (condition-case nil (org-no-warnings (next-line 1)) (error nil))
+ (setq hidep (org-on-heading-p 1)))
+ (eval form)
+ (and hidep (hide-entry))))
+
+(defun org-columns-previous-allowed-value ()
+ "Switch to the previous allowed value for this column."
+ (interactive)
+ (org-columns-next-allowed-value t))
+
+(defun org-columns-next-allowed-value (&optional previous)
+ "Switch to the next allowed value for this column."
+ (interactive)
+ (org-columns-check-computed)
+ (let* ((col (current-column))
+ (key (get-char-property (point) 'org-columns-key))
+ (value (get-char-property (point) 'org-columns-value))
+ (bol (point-at-bol)) (eol (point-at-eol))
+ (pom (or (get-text-property bol 'org-hd-marker)
+ (point))) ; keep despite of compiler waring
+ (line-overlays
+ (delq nil (mapcar (lambda (x)
+ (and (eq (overlay-buffer x) (current-buffer))
+ (>= (overlay-start x) bol)
+ (<= (overlay-start x) eol)
+ x))
+ org-columns-overlays)))
+ (allowed (or (org-property-get-allowed-values pom key)
+ (and (memq
+ (nth 4 (assoc key org-columns-current-fmt-compiled))
+ '(checkbox checkbox-n-of-m checkbox-percent))
+ '("[ ]" "[X]"))))
+ nval)
+ (when (equal key "ITEM")
+ (error "Cannot edit item headline from here"))
+ (unless (or allowed (member key '("SCHEDULED" "DEADLINE")))
+ (error "Allowed values for this property have not been defined"))
+ (if (member key '("SCHEDULED" "DEADLINE"))
+ (setq nval (if previous 'earlier 'later))
+ (if previous (setq allowed (reverse allowed)))
+ (if (member value allowed)
+ (setq nval (car (cdr (member value allowed)))))
+ (setq nval (or nval (car allowed)))
+ (if (equal nval value)
+ (error "Only one allowed value for this property")))
+ (let ((inhibit-read-only t))
+ (remove-text-properties (1- bol) eol '(read-only t))
+ (unwind-protect
+ (progn
+ (setq org-columns-overlays
+ (org-delete-all line-overlays org-columns-overlays))
+ (mapc 'org-delete-overlay line-overlays)
+ (org-columns-eval '(org-entry-put pom key nval)))
+ (org-columns-display-here)))
+ (move-to-column col)
+ (if (and (org-mode-p)
+ (nth 3 (assoc key org-columns-current-fmt-compiled)))
+ (org-columns-update key))))
+
+(defun org-verify-version (task)
+ (cond
+ ((eq task 'columns)
+ (if (or (featurep 'xemacs)
+ (< emacs-major-version 22))
+ (error "Emacs 22 is required for the columns feature")))))
+
+(defun org-columns-open-link (&optional arg)
+ (interactive "P")
+ (let ((value (get-char-property (point) 'org-columns-value)))
+ (org-open-link-from-string value arg)))
+
+(defun org-open-link-from-string (s &optional arg)
+ "Open a link in the string S, as if it was in Org-mode."
+ (interactive)
+ (with-temp-buffer
+ (let ((org-inhibit-startup t))
+ (org-mode)
+ (insert s)
+ (goto-char (point-min))
+ (org-open-at-point arg))))
+
+(defun org-columns-get-format-and-top-level ()
+ (let (fmt)
+ (when (condition-case nil (org-back-to-heading) (error nil))
+ (move-marker org-entry-property-inherited-from nil)
+ (setq fmt (org-entry-get nil "COLUMNS" t)))
+ (setq fmt (or fmt org-columns-default-format))
+ (org-set-local 'org-columns-current-fmt fmt)
+ (org-columns-compile-format fmt)
+ (if (marker-position org-entry-property-inherited-from)
+ (move-marker org-columns-top-level-marker
+ org-entry-property-inherited-from)
+ (move-marker org-columns-top-level-marker (point)))
+ fmt))
+
+(defun org-columns ()
+ "Turn on column view on an org-mode file."
+ (interactive)
+ (org-verify-version 'columns)
+ (org-columns-remove-overlays)
+ (move-marker org-columns-begin-marker (point))
+ (let (beg end fmt cache maxwidths)
+ (setq fmt (org-columns-get-format-and-top-level))
+ (save-excursion
+ (goto-char org-columns-top-level-marker)
+ (setq beg (point))
+ (unless org-columns-inhibit-recalculation
+ (org-columns-compute-all))
+ (setq end (or (condition-case nil (org-end-of-subtree t t) (error nil))
+ (point-max)))
+ ;; Get and cache the properties
+ (goto-char beg)
+ (when (assoc "CLOCKSUM" org-columns-current-fmt-compiled)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (org-clock-sum))))
+ (while (re-search-forward (concat "^" outline-regexp) end t)
+ (push (cons (org-current-line) (org-entry-properties)) cache))
+ (when cache
+ (setq maxwidths (org-columns-get-autowidth-alist fmt cache))
+ (org-set-local 'org-columns-current-maxwidths maxwidths)
+ (org-columns-display-here-title)
+ (mapc (lambda (x)
+ (goto-line (car x))
+ (org-columns-display-here (cdr x)))
+ cache)))))
+
+(defun org-columns-new (&optional prop title width op fmt &rest rest)
+ "Insert a new column, to the left of the current column."
+ (interactive)
+ (let ((editp (and prop (assoc prop org-columns-current-fmt-compiled)))
+ cell)
+ (setq prop (completing-read
+ "Property: " (mapcar 'list (org-buffer-property-keys t nil t))
+ nil nil prop))
+ (setq title (read-string (concat "Column title [" prop "]: ") (or title prop)))
+ (setq width (read-string "Column width: " (if width (number-to-string width))))
+ (if (string-match "\\S-" width)
+ (setq width (string-to-number width))
+ (setq width nil))
+ (setq fmt (completing-read "Summary [none]: "
+ '(("none") ("add_numbers") ("currency") ("add_times") ("checkbox") ("checkbox-n-of-m") ("checkbox-percent"))
+ nil t))
+ (if (string-match "\\S-" fmt)
+ (setq fmt (intern fmt))
+ (setq fmt nil))
+ (if (eq fmt 'none) (setq fmt nil))
+ (if editp
+ (progn
+ (setcar editp prop)
+ (setcdr editp (list title width nil fmt)))
+ (setq cell (nthcdr (1- (current-column))
+ org-columns-current-fmt-compiled))
+ (setcdr cell (cons (list prop title width nil fmt)
+ (cdr cell))))
+ (org-columns-store-format)
+ (org-columns-redo)))
+
+(defun org-columns-delete ()
+ "Delete the column at point from columns view."
+ (interactive)
+ (let* ((n (current-column))
+ (title (nth 1 (nth n org-columns-current-fmt-compiled))))
+ (when (y-or-n-p
+ (format "Are you sure you want to remove column \"%s\"? " title))
+ (setq org-columns-current-fmt-compiled
+ (delq (nth n org-columns-current-fmt-compiled)
+ org-columns-current-fmt-compiled))
+ (org-columns-store-format)
+ (org-columns-redo)
+ (if (>= (current-column) (length org-columns-current-fmt-compiled))
+ (backward-char 1)))))
+
+(defun org-columns-edit-attributes ()
+ "Edit the attributes of the current column."
+ (interactive)
+ (let* ((n (current-column))
+ (info (nth n org-columns-current-fmt-compiled)))
+ (apply 'org-columns-new info)))
+
+(defun org-columns-widen (arg)
+ "Make the column wider by ARG characters."
+ (interactive "p")
+ (let* ((n (current-column))
+ (entry (nth n org-columns-current-fmt-compiled))
+ (width (or (nth 2 entry)
+ (cdr (assoc (car entry) org-columns-current-maxwidths)))))
+ (setq width (max 1 (+ width arg)))
+ (setcar (nthcdr 2 entry) width)
+ (org-columns-store-format)
+ (org-columns-redo)))
+
+(defun org-columns-narrow (arg)
+ "Make the column nrrower by ARG characters."
+ (interactive "p")
+ (org-columns-widen (- arg)))
+
+(defun org-columns-move-right ()
+ "Swap this column with the one to the right."
+ (interactive)
+ (let* ((n (current-column))
+ (cell (nthcdr n org-columns-current-fmt-compiled))
+ e)
+ (when (>= n (1- (length org-columns-current-fmt-compiled)))
+ (error "Cannot shift this column further to the right"))
+ (setq e (car cell))
+ (setcar cell (car (cdr cell)))
+ (setcdr cell (cons e (cdr (cdr cell))))
+ (org-columns-store-format)
+ (org-columns-redo)
+ (forward-char 1)))
+
+(defun org-columns-move-left ()
+ "Swap this column with the one to the left."
+ (interactive)
+ (let* ((n (current-column)))
+ (when (= n 0)
+ (error "Cannot shift this column further to the left"))
+ (backward-char 1)
+ (org-columns-move-right)
+ (backward-char 1)))
+
+(defun org-columns-store-format ()
+ "Store the text version of the current columns format in appropriate place.
+This is either in the COLUMNS property of the node starting the current column
+display, or in the #+COLUMNS line of the current buffer."
+ (let (fmt (cnt 0))
+ (setq fmt (org-columns-uncompile-format org-columns-current-fmt-compiled))
+ (org-set-local 'org-columns-current-fmt fmt)
+ (if (marker-position org-columns-top-level-marker)
+ (save-excursion
+ (goto-char org-columns-top-level-marker)
+ (if (and (org-at-heading-p)
+ (org-entry-get nil "COLUMNS"))
+ (org-entry-put nil "COLUMNS" fmt)
+ (goto-char (point-min))
+ ;; Overwrite all #+COLUMNS lines....
+ (while (re-search-forward "^#\\+COLUMNS:.*" nil t)
+ (setq cnt (1+ cnt))
+ (replace-match (concat "#+COLUMNS: " fmt) t t))
+ (unless (> cnt 0)
+ (goto-char (point-min))
+ (or (org-on-heading-p t) (outline-next-heading))
+ (let ((inhibit-read-only t))
+ (insert-before-markers "#+COLUMNS: " fmt "\n")))
+ (org-set-local 'org-columns-default-format fmt))))))
+
+(defvar org-overriding-columns-format nil
+ "When set, overrides any other definition.")
+(defvar org-agenda-view-columns-initially nil
+ "When set, switch to columns view immediately after creating the agenda.")
+
+(defun org-agenda-columns ()
+ "Turn on column view in the agenda."
+ (interactive)
+ (org-verify-version 'columns)
+ (org-columns-remove-overlays)
+ (move-marker org-columns-begin-marker (point))
+ (let (fmt cache maxwidths m)
+ (cond
+ ((and (local-variable-p 'org-overriding-columns-format)
+ org-overriding-columns-format)
+ (setq fmt org-overriding-columns-format))
+ ((setq m (get-text-property (point-at-bol) 'org-hd-marker))
+ (setq fmt (org-entry-get m "COLUMNS" t)))
+ ((and (boundp 'org-columns-current-fmt)
+ (local-variable-p 'org-columns-current-fmt)
+ org-columns-current-fmt)
+ (setq fmt org-columns-current-fmt))
+ ((setq m (next-single-property-change (point-min) 'org-hd-marker))
+ (setq m (get-text-property m 'org-hd-marker))
+ (setq fmt (org-entry-get m "COLUMNS" t))))
+ (setq fmt (or fmt org-columns-default-format))
+ (org-set-local 'org-columns-current-fmt fmt)
+ (org-columns-compile-format fmt)
+ (save-excursion
+ ;; Get and cache the properties
+ (goto-char (point-min))
+ (while (not (eobp))
+ (when (setq m (or (get-text-property (point) 'org-hd-marker)
+ (get-text-property (point) 'org-marker)))
+ (push (cons (org-current-line) (org-entry-properties m)) cache))
+ (beginning-of-line 2))
+ (when cache
+ (setq maxwidths (org-columns-get-autowidth-alist fmt cache))
+ (org-set-local 'org-columns-current-maxwidths maxwidths)
+ (org-columns-display-here-title)
+ (mapc (lambda (x)
+ (goto-line (car x))
+ (org-columns-display-here (cdr x)))
+ cache)))))
+
+(defun org-columns-get-autowidth-alist (s cache)
+ "Derive the maximum column widths from the format and the cache."
+ (let ((start 0) rtn)
+ (while (string-match (org-re "%\\([[:alpha:]][[:alnum:]_-]*\\)") s start)
+ (push (cons (match-string 1 s) 1) rtn)
+ (setq start (match-end 0)))
+ (mapc (lambda (x)
+ (setcdr x (apply 'max
+ (mapcar
+ (lambda (y)
+ (length (or (cdr (assoc (car x) (cdr y))) " ")))
+ cache))))
+ rtn)
+ rtn))
+
+(defun org-columns-compute-all ()
+ "Compute all columns that have operators defined."
+ (org-unmodified
+ (remove-text-properties (point-min) (point-max) '(org-summaries t)))
+ (let ((columns org-columns-current-fmt-compiled) col)
+ (while (setq col (pop columns))
+ (when (nth 3 col)
+ (save-excursion
+ (org-columns-compute (car col)))))))
+
+(defun org-columns-update (property)
+ "Recompute PROPERTY, and update the columns display for it."
+ (org-columns-compute property)
+ (let (fmt val pos)
+ (save-excursion
+ (mapc (lambda (ov)
+ (when (equal (org-overlay-get ov 'org-columns-key) property)
+ (setq pos (org-overlay-start ov))
+ (goto-char pos)
+ (when (setq val (cdr (assoc property
+ (get-text-property
+ (point-at-bol) 'org-summaries))))
+ (setq fmt (org-overlay-get ov 'org-columns-format))
+ (org-overlay-put ov 'org-columns-value val)
+ (org-overlay-put ov 'display (format fmt val)))))
+ org-columns-overlays))))
+
+(defun org-columns-compute (property)
+ "Sum the values of property PROPERTY hierarchically, for the entire buffer."
+ (interactive)
+ (let* ((re (concat "^" outline-regexp))
+ (lmax 30) ; Does anyone use deeper levels???
+ (lsum (make-vector lmax 0))
+ (lflag (make-vector lmax nil))
+ (level 0)
+ (ass (assoc property org-columns-current-fmt-compiled))
+ (format (nth 4 ass))
+ (printf (nth 5 ass))
+ (beg org-columns-top-level-marker)
+ last-level val valflag flag end sumpos sum-alist sum str str1 useval)
+ (save-excursion
+ ;; Find the region to compute
+ (goto-char beg)
+ (setq end (condition-case nil (org-end-of-subtree t) (error (point-max))))
+ (goto-char end)
+ ;; Walk the tree from the back and do the computations
+ (while (re-search-backward re beg t)
+ (setq sumpos (match-beginning 0)
+ last-level level
+ level (org-outline-level)
+ val (org-entry-get nil property)
+ valflag (and val (string-match "\\S-" val)))
+ (cond
+ ((< level last-level)
+ ;; put the sum of lower levels here as a property
+ (setq sum (aref lsum last-level) ; current sum
+ flag (aref lflag last-level) ; any valid entries from children?
+ str (org-column-number-to-string sum format printf)
+ str1 (org-add-props (copy-sequence str) nil 'org-computed t 'face 'bold)
+ useval (if flag str1 (if valflag val ""))
+ sum-alist (get-text-property sumpos 'org-summaries))
+ (if (assoc property sum-alist)
+ (setcdr (assoc property sum-alist) useval)
+ (push (cons property useval) sum-alist)
+ (org-unmodified
+ (add-text-properties sumpos (1+ sumpos)
+ (list 'org-summaries sum-alist))))
+ (when val
+ (org-entry-put nil property (if flag str val)))
+ ;; add current to current level accumulator
+ (when (or flag valflag)
+ (aset lsum level (+ (aref lsum level)
+ (if flag sum (org-column-string-to-number
+ (if flag str val) format))))
+ (aset lflag level t))
+ ;; clear accumulators for deeper levels
+ (loop for l from (1+ level) to (1- lmax) do
+ (aset lsum l 0)
+ (aset lflag l nil)))
+ ((>= level last-level)
+ ;; add what we have here to the accumulator for this level
+ (aset lsum level (+ (aref lsum level)
+ (org-column-string-to-number (or val "0") format)))
+ (and valflag (aset lflag level t)))
+ (t (error "This should not happen")))))))
+
+(defun org-columns-redo ()
+ "Construct the column display again."
+ (interactive)
+ (message "Recomputing columns...")
+ (save-excursion
+ (if (marker-position org-columns-begin-marker)
+ (goto-char org-columns-begin-marker))
+ (org-columns-remove-overlays)
+ (if (org-mode-p)
+ (call-interactively 'org-columns)
+ (call-interactively 'org-agenda-columns)))
+ (message "Recomputing columns...done"))
+
+(defun org-columns-not-in-agenda ()
+ (if (eq major-mode 'org-agenda-mode)
+ (error "This command is only allowed in Org-mode buffers")))
+
+
+(defun org-string-to-number (s)
+ "Convert string to number, and interpret hh:mm:ss."
+ (if (not (string-match ":" s))
+ (string-to-number s)
+ (let ((l (nreverse (org-split-string s ":"))) (sum 0.0))
+ (while l
+ (setq sum (+ (string-to-number (pop l)) (/ sum 60))))
+ sum)))
+
+(defun org-column-number-to-string (n fmt &optional printf)
+ "Convert a computed column number to a string value, according to FMT."
+ (cond
+ ((eq fmt 'add_times)
+ (let* ((h (floor n)) (m (floor (+ 0.5 (* 60 (- n h))))))
+ (format "%d:%02d" h m)))
+ ((eq fmt 'checkbox)
+ (cond ((= n (floor n)) "[X]")
+ ((> n 1.) "[-]")
+ (t "[ ]")))
+ ((memq fmt '(checkbox-n-of-m checkbox-percent))
+ (let* ((n1 (floor n)) (n2 (floor (+ .5 (* 1000000 (- n n1))))))
+ (org-nofm-to-completion n1 (+ n2 n1) (eq fmt 'checkbox-percent))))
+ (printf (format printf n))
+ ((eq fmt 'currency)
+ (format "%.2f" n))
+ (t (number-to-string n))))
+
+(defun org-nofm-to-completion (n m &optional percent)
+ (if (not percent)
+ (format "[%d/%d]" n m)
+ (format "[%d%%]"(floor (+ 0.5 (* 100. (/ (* 1.0 n) m)))))))
+
+(defun org-column-string-to-number (s fmt)
+ "Convert a column value to a number that can be used for column computing."
+ (cond
+ ((string-match ":" s)
+ (let ((l (nreverse (org-split-string s ":"))) (sum 0.0))
+ (while l
+ (setq sum (+ (string-to-number (pop l)) (/ sum 60))))
+ sum))
+ ((memq fmt '(checkbox checkbox-n-of-m checkbox-percent))
+ (if (equal s "[X]") 1. 0.000001))
+ (t (string-to-number s))))
+
+(defun org-columns-uncompile-format (cfmt)
+ "Turn the compiled columns format back into a string representation."
+ (let ((rtn "") e s prop title op width fmt printf)
+ (while (setq e (pop cfmt))
+ (setq prop (car e)
+ title (nth 1 e)
+ width (nth 2 e)
+ op (nth 3 e)
+ fmt (nth 4 e)
+ printf (nth 5 e))
+ (cond
+ ((eq fmt 'add_times) (setq op ":"))
+ ((eq fmt 'checkbox) (setq op "X"))
+ ((eq fmt 'checkbox-n-of-m) (setq op "X/"))
+ ((eq fmt 'checkbox-percent) (setq op "X%"))
+ ((eq fmt 'add_numbers) (setq op "+"))
+ ((eq fmt 'currency) (setq op "$")))
+ (if (and op printf) (setq op (concat op ";" printf)))
+ (if (equal title prop) (setq title nil))
+ (setq s (concat "%" (if width (number-to-string width))
+ prop
+ (if title (concat "(" title ")"))
+ (if op (concat "{" op "}"))))
+ (setq rtn (concat rtn " " s)))
+ (org-trim rtn)))
+
+(defun org-columns-compile-format (fmt)
+ "Turn a column format string into an alist of specifications.
+The alist has one entry for each column in the format. The elements of
+that list are:
+property the property
+title the title field for the columns
+width the column width in characters, can be nil for automatic
+operator the operator if any
+format the output format for computed results, derived from operator
+printf a printf format for computed values"
+ (let ((start 0) width prop title op f printf)
+ (setq org-columns-current-fmt-compiled nil)
+ (while (string-match
+ (org-re "%\\([0-9]+\\)?\\([[:alnum:]_-]+\\)\\(?:(\\([^)]+\\))\\)?\\(?:{\\([^}]+\\)}\\)?\\s-*")
+ fmt start)
+ (setq start (match-end 0)
+ width (match-string 1 fmt)
+ prop (match-string 2 fmt)
+ title (or (match-string 3 fmt) prop)
+ op (match-string 4 fmt)
+ f nil
+ printf nil)
+ (if width (setq width (string-to-number width)))
+ (when (and op (string-match ";" op))
+ (setq printf (substring op (match-end 0))
+ op (substring op 0 (match-beginning 0))))
+ (cond
+ ((equal op "+") (setq f 'add_numbers))
+ ((equal op "$") (setq f 'currency))
+ ((equal op ":") (setq f 'add_times))
+ ((equal op "X") (setq f 'checkbox))
+ ((equal op "X/") (setq f 'checkbox-n-of-m))
+ ((equal op "X%") (setq f 'checkbox-percent))
+ )
+ (push (list prop title width op f printf) org-columns-current-fmt-compiled))
+ (setq org-columns-current-fmt-compiled
+ (nreverse org-columns-current-fmt-compiled))))
+
+
+;;; Dynamic block for Column view
+
+(defun org-columns-capture-view (&optional maxlevel skip-empty-rows)
+ "Get the column view of the current buffer or subtree.
+The first optional argument MAXLEVEL sets the level limit. A
+second optional argument SKIP-EMPTY-ROWS tells whether to skip
+empty rows, an empty row being one where all the column view
+specifiers except ITEM are empty. This function returns a list
+containing the title row and all other rows. Each row is a list
+of fields."
+ (save-excursion
+ (let* ((title (mapcar 'cadr org-columns-current-fmt-compiled))
+ (n (length title)) row tbl)
+ (goto-char (point-min))
+ (while (and (re-search-forward "^\\(\\*+\\) " nil t)
+ (or (null maxlevel)
+ (>= maxlevel
+ (if org-odd-levels-only
+ (/ (1+ (length (match-string 1))) 2)
+ (length (match-string 1))))))
+ (when (get-char-property (match-beginning 0) 'org-columns-key)
+ (setq row nil)
+ (loop for i from 0 to (1- n) do
+ (push (or (get-char-property (+ (match-beginning 0) i) 'org-columns-value-modified)
+ (get-char-property (+ (match-beginning 0) i) 'org-columns-value)
+ "")
+ row))
+ (setq row (nreverse row))
+ (unless (and skip-empty-rows
+ (eq 1 (length (delete "" (delete-dups row)))))
+ (push row tbl))))
+ (append (list title 'hline) (nreverse tbl)))))
+
+(defun org-dblock-write:columnview (params)
+ "Write the column view table.
+PARAMS is a property list of parameters:
+
+:width enforce same column widths with <N> specifiers.
+:id the :ID: property of the entry where the columns view
+ should be built, as a string. When `local', call locally.
+ When `global' call column view with the cursor at the beginning
+ of the buffer (usually this means that the whole buffer switches
+ to column view).
+:hlines When t, insert a hline before each item. When a number, insert
+ a hline before each level <= that number.
+:vlines When t, make each column a colgroup to enforce vertical lines.
+:maxlevel When set to a number, don't capture headlines below this level.
+:skip-empty-rows
+ When t, skip rows where all specifiers other than ITEM are empty."
+ (let ((pos (move-marker (make-marker) (point)))
+ (hlines (plist-get params :hlines))
+ (vlines (plist-get params :vlines))
+ (maxlevel (plist-get params :maxlevel))
+ (skip-empty-rows (plist-get params :skip-empty-rows))
+ tbl id idpos nfields tmp)
+ (save-excursion
+ (save-restriction
+ (when (setq id (plist-get params :id))
+ (cond ((not id) nil)
+ ((eq id 'global) (goto-char (point-min)))
+ ((eq id 'local) nil)
+ ((setq idpos (org-find-entry-with-id id))
+ (goto-char idpos))
+ (t (error "Cannot find entry with :ID: %s" id))))
+ (org-columns)
+ (setq tbl (org-columns-capture-view maxlevel skip-empty-rows))
+ (setq nfields (length (car tbl)))
+ (org-columns-quit)))
+ (goto-char pos)
+ (move-marker pos nil)
+ (when tbl
+ (when (plist-get params :hlines)
+ (setq tmp nil)
+ (while tbl
+ (if (eq (car tbl) 'hline)
+ (push (pop tbl) tmp)
+ (if (string-match "\\` *\\(\\*+\\)" (caar tbl))
+ (if (and (not (eq (car tmp) 'hline))
+ (or (eq hlines t)
+ (and (numberp hlines) (<= (- (match-end 1) (match-beginning 1)) hlines))))
+ (push 'hline tmp)))
+ (push (pop tbl) tmp)))
+ (setq tbl (nreverse tmp)))
+ (when vlines
+ (setq tbl (mapcar (lambda (x)
+ (if (eq 'hline x) x (cons "" x)))
+ tbl))
+ (setq tbl (append tbl (list (cons "/" (make-list nfields "<>"))))))
+ (setq pos (point))
+ (insert (org-listtable-to-string tbl))
+ (when (plist-get params :width)
+ (insert "\n|" (mapconcat (lambda (x) (format "<%d>" (max 3 x)))
+ org-columns-current-widths "|")))
+ (goto-char pos)
+ (org-table-align))))
+
+(defun org-listtable-to-string (tbl)
+ "Convert a listtable TBL to a string that contains the Org-mode table.
+The table still need to be alligned. The resulting string has no leading
+and tailing newline characters."
+ (mapconcat
+ (lambda (x)
+ (cond
+ ((listp x)
+ (concat "|" (mapconcat 'identity x "|") "|"))
+ ((eq x 'hline) "|-|")
+ (t (error "Garbage in listtable: %s" x))))
+ tbl "\n"))
+
+(defun org-insert-columns-dblock ()
+ "Create a dynamic block capturing a column view table."
+ (interactive)
+ (let ((defaults '(:name "columnview" :hlines 1))
+ (id (completing-read
+ "Capture columns (local, global, entry with :ID: property) [local]: "
+ (append '(("global") ("local"))
+ (mapcar 'list (org-property-values "ID"))))))
+ (if (equal id "") (setq id 'local))
+ (if (equal id "global") (setq id 'global))
+ (setq defaults (append defaults (list :id id)))
+ (org-create-dblock defaults)
+ (org-update-dblock)))
+
;;;; Timestamps
(defvar org-last-changed-timestamp nil)
(defvar org-time-was-given) ; dynamically scoped parameter
+(defvar org-end-time-was-given) ; dynamically scoped parameter
(defvar org-ts-what) ; dynamically scoped parameter
(defun org-time-stamp (arg)
will represent the current date/time. If there is already a timestamp
at the cursor, it will be modified."
(interactive "P")
- (let (org-time-was-given time)
+ (let* ((ts nil)
+ (default-time
+ ;; Default time is either today, or, when entering a range,
+ ;; the range start.
+ (if (or (and (org-at-timestamp-p t) (setq ts (match-string 0)))
+ (save-excursion
+ (re-search-backward
+ (concat org-ts-regexp "--?-?\\=") ; 1-3 minuses
+ (- (point) 20) t)))
+ (apply 'encode-time (org-parse-time-string (match-string 1)))
+ (current-time)))
+ (default-input (and ts (org-get-compact-tod ts)))
+ org-time-was-given org-end-time-was-given time)
(cond
((and (org-at-timestamp-p)
(eq last-command 'org-time-stamp)
(eq this-command 'org-time-stamp))
(insert "--")
(setq time (let ((this-command this-command))
- (org-read-date arg 'totime)))
+ (org-read-date arg 'totime nil nil default-time default-input)))
(org-insert-time-stamp time (or org-time-was-given arg)))
((org-at-timestamp-p)
(setq time (let ((this-command this-command))
- (org-read-date arg 'totime)))
+ (org-read-date arg 'totime nil nil default-time default-input)))
(when (org-at-timestamp-p) ; just to get the match data
(replace-match "")
(setq org-last-changed-timestamp
- (org-insert-time-stamp time (or org-time-was-given arg))))
+ (org-insert-time-stamp
+ time (or org-time-was-given arg)
+ nil nil nil (list org-end-time-was-given))))
(message "Timestamp updated"))
(t
(setq time (let ((this-command this-command))
- (org-read-date arg 'totime)))
- (org-insert-time-stamp time (or org-time-was-given arg))))))
+ (org-read-date arg 'totime nil nil default-time default-input)))
+ (org-insert-time-stamp time (or org-time-was-given arg)
+ nil nil nil (list org-end-time-was-given))))))
+
+;; FIXME: can we use this for something else????
+;; like computing time differences?????
+(defun org-get-compact-tod (s)
+ (when (string-match "\\(\\([012]?[0-9]\\):\\([0-5][0-9]\\)\\)\\(-\\(\\([012]?[0-9]\\):\\([0-5][0-9]\\)\\)\\)?" s)
+ (let* ((t1 (match-string 1 s))
+ (h1 (string-to-number (match-string 2 s)))
+ (m1 (string-to-number (match-string 3 s)))
+ (t2 (and (match-end 4) (match-string 5 s)))
+ (h2 (and t2 (string-to-number (match-string 6 s))))
+ (m2 (and t2 (string-to-number (match-string 7 s))))
+ dh dm)
+ (if (not t2)
+ t1
+ (setq dh (- h2 h1) dm (- m2 m1))
+ (if (< dm 0) (setq dm (+ dm 60) dh (1- dh)))
+ (concat t1 "+" (number-to-string dh)
+ (if (/= 0 dm) (concat ":" (number-to-string dm))))))))
(defun org-time-stamp-inactive (&optional arg)
"Insert an inactive time stamp.
does not link to the calendar and cannot be changed with the S-cursor keys.
So these are more for recording a certain time/date."
(interactive "P")
- (let (org-time-was-given time)
+ (let (org-time-was-given org-end-time-was-given time)
(setq time (org-read-date arg 'totime))
- (org-insert-time-stamp time (or org-time-was-given arg) 'inactive)))
+ (org-insert-time-stamp time (or org-time-was-given arg) 'inactive
+ nil nil (list org-end-time-was-given))))
(defvar org-date-ovl (org-make-overlay 1 1))
(org-overlay-put org-date-ovl 'face 'org-warning)
(defvar org-ans1) ; dynamically scoped parameter
(defvar org-ans2) ; dynamically scoped parameter
-(defun org-read-date (&optional with-time to-time from-string prompt)
- "Read a date and make things smooth for the user.
+(defvar org-plain-time-of-day-regexp) ; defined below
+
+(defvar org-read-date-overlay nil)
+(defvar org-dcst nil) ; dynamically scoped
+
+(defun org-read-date (&optional with-time to-time from-string prompt
+ default-time default-input)
+ "Read a date, possibly a time, and make things smooth for the user.
The prompt will suggest to enter an ISO date, but you can also enter anything
which will at least partially be understood by `parse-time-string'.
Unrecognized parts of the date will default to the current day, month, year,
-hour and minute. For example,
+hour and minute. If this command is called to replace a timestamp at point,
+of to enter the second timestamp of a range, the default time is taken from the
+existing stamp. For example,
3-2-5 --> 2003-02-05
feb 15 --> currentyear-02-15
sep 12 9 --> 2009-09-12
22 sept 0:34 --> currentyear-09-22 0:34
12 --> currentyear-currentmonth-12
Fri --> nearest Friday (today or later)
- +4 --> four days from today (only if +N is the only thing given)
etc.
+
+Furthermore you can specify a relative date by giving, as the *first* thing
+in the input: a plus/minus sign, a number and a letter [dwmy] to indicate
+change in days weeks, months, years.
+With a single plus or minus, the date is relative to today. With a double
+plus or minus, it is relative to the date in DEFAULT-TIME. E.g.
+ +4d --> four days from today
+ +4 --> same as above
+ +2w --> two weeks from today
+ ++5 --> five days from default date
+
The function understands only English month and weekday abbreviations,
but this can be configured with the variables `parse-time-months' and
`parse-time-weekdays'.
date with the mouse (button 1). The calendar shows a period of three
months. To scroll it to other months, use the keys `>' and `<'.
If you don't like the calendar, turn it off with
- \(setq org-popup-calendar-for-date-prompt nil)
+ \(setq org-read-date-popup-calendar nil)
With optional argument TO-TIME, the date will immediately be converted
to an internal time.
insert a time. Note that when WITH-TIME is not set, you can still
enter a time, and this function will inform the calling routine about
this change. The calling routine may then choose to change the format
-used to insert the time stamp into the buffer to include the time."
+used to insert the time stamp into the buffer to include the time.
+With optional argument FROM-STRING, read from this string instead from
+the user. PROMPT can overwrite the default prompt. DEFAULT-TIME is
+the time/date that is used for everything that is not specified by the
+user."
(require 'parse-time)
(let* ((org-time-stamp-rounding-minutes
- (if (equal with-time '(16)) 0 org-time-stamp-rounding-minutes))
+ (if (equal with-time '(16)) '(0 0) org-time-stamp-rounding-minutes))
+ (org-dcst org-display-custom-times)
(ct (org-current-time))
- (default-time
- ;; Default time is either today, or, when entering a range,
- ;; the range start.
- (if (save-excursion
- (re-search-backward
- (concat org-ts-regexp "--?-?\\=") ; 1-3 minuses
- (- (point) 20) t))
- (apply
- 'encode-time
- (mapcar (lambda(x) (or x 0))
- (parse-time-string (match-string 1))))
- ct))
+ (def (or default-time ct))
+ (defdecode (decode-time def))
+ (dummy (progn
+ (when (< (nth 2 defdecode) org-extend-today-until)
+ (setcar (nthcdr 2 defdecode) -1)
+ (setcar (nthcdr 1 defdecode) 59)
+ (setq def (apply 'encode-time defdecode)
+ defdecode (decode-time def)))))
(calendar-move-hook nil)
+ (calendar-view-diary-initially-flag nil)
(view-diary-entries-initially nil)
+ (calendar-view-holidays-initially-flag nil)
(view-calendar-holidays-initially nil)
(timestr (format-time-string
- (if with-time "%Y-%m-%d %H:%M" "%Y-%m-%d") default-time))
+ (if with-time "%Y-%m-%d %H:%M" "%Y-%m-%d") def))
(prompt (concat (if prompt (concat prompt " ") "")
- (format "YYYY-MM-DD [%s]: " timestr)))
- ans (org-ans0 "") org-ans1 org-ans2 (deltadays 0)
- second minute hour day month year tl wday wday1)
+ (format "Date+time [%s]: " timestr)))
+ ans (org-ans0 "") org-ans1 org-ans2 final)
(cond
(from-string (setq ans from-string))
- (org-popup-calendar-for-date-prompt
+ (org-read-date-popup-calendar
(save-excursion
(save-window-excursion
(calendar)
- (calendar-forward-day (- (time-to-days default-time)
+ (calendar-forward-day (- (time-to-days def)
(calendar-absolute-from-gregorian
(calendar-current-date))))
- (org-eval-in-calendar nil)
+ (org-eval-in-calendar nil t)
(let* ((old-map (current-local-map))
(map (copy-keymap calendar-mode-map))
(minibuffer-local-map (copy-keymap minibuffer-local-map)))
- (define-key map (kbd "RET") 'org-calendar-select)
- (define-key map (if (featurep 'xemacs) [button1] [mouse-1])
+ (org-defkey map (kbd "RET") 'org-calendar-select)
+ (org-defkey map (if (featurep 'xemacs) [button1] [mouse-1])
'org-calendar-select-mouse)
- (define-key map (if (featurep 'xemacs) [button2] [mouse-2])
+ (org-defkey map (if (featurep 'xemacs) [button2] [mouse-2])
'org-calendar-select-mouse)
- (define-key minibuffer-local-map [(meta shift left)]
+ (org-defkey minibuffer-local-map [(meta shift left)]
(lambda () (interactive)
(org-eval-in-calendar '(calendar-backward-month 1))))
- (define-key minibuffer-local-map [(meta shift right)]
+ (org-defkey minibuffer-local-map [(meta shift right)]
(lambda () (interactive)
(org-eval-in-calendar '(calendar-forward-month 1))))
- (define-key minibuffer-local-map [(shift up)]
+ (org-defkey minibuffer-local-map [(meta shift up)]
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-backward-year 1))))
+ (org-defkey minibuffer-local-map [(meta shift down)]
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-forward-year 1))))
+ (org-defkey minibuffer-local-map [(shift up)]
(lambda () (interactive)
(org-eval-in-calendar '(calendar-backward-week 1))))
- (define-key minibuffer-local-map [(shift down)]
+ (org-defkey minibuffer-local-map [(shift down)]
(lambda () (interactive)
(org-eval-in-calendar '(calendar-forward-week 1))))
- (define-key minibuffer-local-map [(shift left)]
+ (org-defkey minibuffer-local-map [(shift left)]
(lambda () (interactive)
(org-eval-in-calendar '(calendar-backward-day 1))))
- (define-key minibuffer-local-map [(shift right)]
+ (org-defkey minibuffer-local-map [(shift right)]
(lambda () (interactive)
(org-eval-in-calendar '(calendar-forward-day 1))))
- (define-key minibuffer-local-map ">"
+ (org-defkey minibuffer-local-map ">"
(lambda () (interactive)
(org-eval-in-calendar '(scroll-calendar-left 1))))
- (define-key minibuffer-local-map "<"
+ (org-defkey minibuffer-local-map "<"
(lambda () (interactive)
(org-eval-in-calendar '(scroll-calendar-right 1))))
(unwind-protect
(progn
(use-local-map map)
- (setq org-ans0 (read-string prompt "" nil nil))
-; (if (not (string-match "\\S-" org-ans0)) (setq org-ans0 nil))
+ (add-hook 'post-command-hook 'org-read-date-display)
+ (setq org-ans0 (read-string prompt default-input nil nil))
;; org-ans0: from prompt
;; org-ans1: from mouse click
;; org-ans2: from calendar motion
(setq ans (concat org-ans0 " " (or org-ans1 org-ans2))))
- (use-local-map old-map))))))
+ (remove-hook 'post-command-hook 'org-read-date-display)
+ (use-local-map old-map)
+ (when org-read-date-overlay
+ (org-delete-overlay org-read-date-overlay)
+ (setq org-read-date-overlay nil)))))))
+
(t ; Naked prompt only
- (setq ans (read-string prompt "" nil timestr))))
- (org-detach-overlay org-date-ovl)
+ (unwind-protect
+ (setq ans (read-string prompt default-input nil timestr))
+ (when org-read-date-overlay
+ (org-delete-overlay org-read-date-overlay)
+ (setq org-read-date-overlay nil)))))
- (if (string-match "^[ \t]*[-+][0-9]+[ \t]*$" org-ans0)
- (setq deltadays (string-to-number ans) ans ""))
+ (setq final (org-read-date-analyze ans def defdecode))
+
+ (if to-time
+ (apply 'encode-time final)
+ (if (and (boundp 'org-time-was-given) org-time-was-given)
+ (format "%04d-%02d-%02d %02d:%02d"
+ (nth 5 final) (nth 4 final) (nth 3 final)
+ (nth 2 final) (nth 1 final))
+ (format "%04d-%02d-%02d" (nth 5 final) (nth 4 final) (nth 3 final))))))
+(defvar def)
+(defvar defdecode)
+(defvar with-time)
+(defun org-read-date-display ()
+ "Display the currrent date prompt interpretation in the minibuffer."
+ (when org-read-date-display-live
+ (when org-read-date-overlay
+ (org-delete-overlay org-read-date-overlay))
+ (let ((p (point)))
+ (end-of-line 1)
+ (while (not (equal (buffer-substring
+ (max (point-min) (- (point) 4)) (point))
+ " "))
+ (insert " "))
+ (goto-char p))
+ (let* ((ans (concat (buffer-substring (point-at-bol) (point-max))
+ " " (or org-ans1 org-ans2)))
+ (org-end-time-was-given nil)
+ (f (org-read-date-analyze ans def defdecode))
+ (fmts (if org-dcst
+ org-time-stamp-custom-formats
+ org-time-stamp-formats))
+ (fmt (if (or with-time
+ (and (boundp 'org-time-was-given) org-time-was-given))
+ (cdr fmts)
+ (car fmts)))
+ (txt (concat "=> " (format-time-string fmt (apply 'encode-time f)))))
+ (when (and org-end-time-was-given
+ (string-match org-plain-time-of-day-regexp txt))
+ (setq txt (concat (substring txt 0 (match-end 0)) "-"
+ org-end-time-was-given
+ (substring txt (match-end 0)))))
+ (setq org-read-date-overlay
+ (make-overlay (1- (point-at-eol)) (point-at-eol)))
+ (org-overlay-display org-read-date-overlay txt 'secondary-selection))))
+
+(defun org-read-date-analyze (ans def defdecode)
+ "Analyze the combined answer of the date prompt."
+ ;; FIXME: cleanup and comment
+ (let (delta deltan deltaw deltadef year month day
+ hour minute second wday pm h2 m2 tl wday1)
+
+ (when (setq delta (org-read-date-get-relative ans (current-time) def))
+ (setq ans (replace-match "" t t ans)
+ deltan (car delta)
+ deltaw (nth 1 delta)
+ deltadef (nth 2 delta)))
+
+ ;; Help matching ISO dates with single digit month ot day, like 2006-8-11.
+ (when (string-match
+ "^ *\\(\\([0-9]+\\)-\\)?\\([0-1]?[0-9]\\)-\\([0-3]?[0-9]\\)\\([^-0-9]\\|$\\)" ans)
+ (setq year (if (match-end 2)
+ (string-to-number (match-string 2 ans))
+ (string-to-number (format-time-string "%Y")))
+ month (string-to-number (match-string 3 ans))
+ day (string-to-number (match-string 4 ans)))
+ (if (< year 100) (setq year (+ 2000 year)))
+ (setq ans (replace-match (format "%04d-%02d-%02d\\5" year month day)
+ t nil ans)))
+ ;; Help matching am/pm times, because `parse-time-string' does not do that.
+ ;; If there is a time with am/pm, and *no* time without it, we convert
+ ;; so that matching will be successful.
+ (loop for i from 1 to 2 do ; twice, for end time as well
+ (when (and (not (string-match "\\(\\`\\|[^+]\\)[012]?[0-9]:[0-9][0-9]\\([ \t\n]\\|$\\)" ans))
+ (string-match "\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?\\(am\\|AM\\|pm\\|PM\\)\\>" ans))
+ (setq hour (string-to-number (match-string 1 ans))
+ minute (if (match-end 3)
+ (string-to-number (match-string 3 ans))
+ 0)
+ pm (equal ?p
+ (string-to-char (downcase (match-string 4 ans)))))
+ (if (and (= hour 12) (not pm))
+ (setq hour 0)
+ (if (and pm (< hour 12)) (setq hour (+ 12 hour))))
+ (setq ans (replace-match (format "%02d:%02d" hour minute)
+ t t ans))))
+
+ ;; Check if a time range is given as a duration
+ (when (string-match "\\([012]?[0-9]\\):\\([0-6][0-9]\\)\\+\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?" ans)
+ (setq hour (string-to-number (match-string 1 ans))
+ h2 (+ hour (string-to-number (match-string 3 ans)))
+ minute (string-to-number (match-string 2 ans))
+ m2 (+ minute (if (match-end 5) (string-to-number (match-string 5 ans))0)))
+ (if (>= m2 60) (setq h2 (1+ h2) m2 (- m2 60)))
+ (setq ans (replace-match (format "%02d:%02d-%02d:%02d" hour minute h2 m2) t t ans)))
+
+ ;; Check if there is a time range
+ (when (boundp 'org-end-time-was-given)
+ (setq org-time-was-given nil)
+ (when (and (string-match org-plain-time-of-day-regexp ans)
+ (match-end 8))
+ (setq org-end-time-was-given (match-string 8 ans))
+ (setq ans (concat (substring ans 0 (match-beginning 7))
+ (substring ans (match-end 7))))))
- (if (string-match
- "^ *\\(\\([0-9]+\\)-\\)?\\([0-1]?[0-9]\\)-\\([0-3]?[0-9]\\)\\([^-0-9]\\|$\\)" ans)
- (progn
- (setq year (if (match-end 2)
- (string-to-number (match-string 2 ans))
- (string-to-number (format-time-string "%Y")))
- month (string-to-number (match-string 3 ans))
- day (string-to-number (match-string 4 ans)))
- (if (< year 100) (setq year (+ 2000 year)))
- (setq ans (replace-match (format "%04d-%02d-%02d\\5" year month day)
- t nil ans))))
(setq tl (parse-time-string ans)
- year (or (nth 5 tl) (string-to-number (format-time-string "%Y" ct)))
- month (or (nth 4 tl) (string-to-number (format-time-string "%m" ct)))
- day (or (nth 3 tl) (string-to-number (format-time-string "%d" ct)))
- hour (or (nth 2 tl) (string-to-number (format-time-string "%H" ct)))
- minute (or (nth 1 tl) (string-to-number (format-time-string "%M" ct)))
+ day (or (nth 3 tl) (nth 3 defdecode))
+ month (or (nth 4 tl)
+ (if (and org-read-date-prefer-future
+ (nth 3 tl) (< (nth 3 tl) (nth 3 defdecode)))
+ (1+ (nth 4 defdecode))
+ (nth 4 defdecode)))
+ year (or (nth 5 tl)
+ (if (and org-read-date-prefer-future
+ (nth 4 tl) (< (nth 4 tl) (nth 4 defdecode)))
+ (1+ (nth 5 defdecode))
+ (nth 5 defdecode)))
+ hour (or (nth 2 tl) (nth 2 defdecode))
+ minute (or (nth 1 tl) (nth 1 defdecode))
second (or (nth 0 tl) 0)
wday (nth 6 tl))
- (setq day (+ day deltadays))
+ (when deltan
+ (unless deltadef
+ (let ((now (decode-time (current-time))))
+ (setq day (nth 3 now) month (nth 4 now) year (nth 5 now))))
+ (cond ((member deltaw '("d" "")) (setq day (+ day deltan)))
+ ((equal deltaw "w") (setq day (+ day (* 7 deltan))))
+ ((equal deltaw "m") (setq month (+ month deltan)))
+ ((equal deltaw "y") (setq year (+ year deltan)))))
(when (and wday (not (nth 3 tl)))
;; Weekday was given, but no day, so pick that day in the week
;; on or after the derived date.
(nth 2 tl))
(setq org-time-was-given t))
(if (< year 100) (setq year (+ 2000 year)))
- (if to-time
- (encode-time second minute hour day month year)
- (if (or (nth 1 tl) (nth 2 tl))
- (format "%04d-%02d-%02d %02d:%02d" year month day hour minute)
- (format "%04d-%02d-%02d" year month day)))))
+ (if (< year 1970) (setq year (nth 5 defdecode))) ; not representable
+ (list second minute hour day month year)))
+
+(defvar parse-time-weekdays)
+
+(defun org-read-date-get-relative (s today default)
+ "Check string S for special relative date string.
+TODAY and DEFAULT are internal times, for today and for a default.
+Return shift list (N what def-flag)
+WHAT is \"d\", \"w\", \"m\", or \"y\" for day, week, month, year.
+N is the number of WHATs to shift.
+DEF-FLAG is t when a double ++ or -- indicates shift relative to
+ the DEFAULT date rather than TODAY."
+ (when (and
+ (string-match
+ (concat
+ "\\`[ \t]*\\([-+]\\{0,2\\}\\)"
+ "\\([0-9]+\\)?"
+ "\\([dwmy]\\|\\(" (mapconcat 'car parse-time-weekdays "\\|") "\\)\\)?"
+ "\\([ \t]\\|$\\)") s)
+ (or (> (match-end 1) (match-beginning 1)) (match-end 4)))
+ (let* ((dir (if (> (match-end 1) (match-beginning 1))
+ (string-to-char (substring (match-string 1 s) -1))
+ ?+))
+ (rel (and (match-end 1) (= 2 (- (match-end 1) (match-beginning 1)))))
+ (n (if (match-end 2) (string-to-number (match-string 2 s)) 1))
+ (what (if (match-end 3) (match-string 3 s) "d"))
+ (wday1 (cdr (assoc (downcase what) parse-time-weekdays)))
+ (date (if rel default today))
+ (wday (nth 6 (decode-time date)))
+ delta)
+ (if wday1
+ (progn
+ (setq delta (mod (+ 7 (- wday1 wday)) 7))
+ (if (= dir ?-) (setq delta (- delta 7)))
+ (if (> n 1) (setq delta (+ delta (* (1- n) (if (= dir ?-) -7 7)))))
+ (list delta "d" rel))
+ (list (* n (if (= dir ?-) -1 1)) what rel)))))
-(defun org-eval-in-calendar (form)
+(defun org-eval-in-calendar (form &optional keepdate)
"Eval FORM in the calendar window and return to current window.
Also, store the cursor date in variable org-ans2."
(let ((sw (selected-window)))
(select-window (get-buffer-window "*Calendar*"))
(eval form)
- (when (calendar-cursor-to-date)
+ (when (and (not keepdate) (calendar-cursor-to-date))
(let* ((date (calendar-cursor-to-date))
(time (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date))))
(setq org-ans2 (format-time-string "%Y-%m-%d" time))))
(org-move-overlay org-date-ovl (1- (point)) (1+ (point)) (current-buffer))
(select-window sw)))
+; ;; Update the prompt to show new default date
+; (save-excursion
+; (goto-char (point-min))
+; (when (and org-ans2
+; (re-search-forward "\\[[-0-9]+\\]" nil t)
+; (get-text-property (match-end 0) 'field))
+; (let ((inhibit-read-only t))
+; (replace-match (concat "[" org-ans2 "]") t t)
+; (add-text-properties (point-min) (1+ (match-end 0))
+; (text-properties-at (1+ (point-min)))))))))
+
(defun org-calendar-select ()
"Return to `org-read-date' with the date currently selected.
This is used by `org-read-date' in a temporary keymap for the calendar buffer."
(setq org-ans1 (format-time-string "%Y-%m-%d" time)))
(if (active-minibuffer-window) (exit-minibuffer))))
-(defun org-insert-time-stamp (time &optional with-hm inactive pre post)
+(defun org-insert-time-stamp (time &optional with-hm inactive pre post extra)
"Insert a date stamp for the date given by the internal TIME.
WITH-HM means, use the stamp format that includes the time of the day.
INACTIVE means use square brackets instead of angular ones, so that the
(let ((fmt (funcall (if with-hm 'cdr 'car) org-time-stamp-formats))
stamp)
(if inactive (setq fmt (concat "[" (substring fmt 1 -1) "]")))
- (insert (or pre ""))
- (insert (setq stamp (format-time-string fmt time)))
- (insert (or post ""))
+ (insert-before-markers (or pre ""))
+ (insert-before-markers (setq stamp (format-time-string fmt time)))
+ (when (listp extra)
+ (setq extra (car extra))
+ (if (and (stringp extra)
+ (string-match "\\([0-9]+\\):\\([0-9]+\\)" extra))
+ (setq extra (format "-%02d:%02d"
+ (string-to-number (match-string 1 extra))
+ (string-to-number (match-string 2 extra))))
+ (setq extra nil)))
+ (when extra
+ (backward-char 1)
+ (insert-before-markers extra)
+ (forward-char 1))
+ (insert-before-markers (or post ""))
stamp))
(defun org-toggle-time-stamp-overlays ()
(defun org-display-custom-time (beg end)
"Overlay modified time stamp format over timestamp between BED and END."
- (let* ((t1 (save-match-data
- (org-parse-time-string (buffer-substring beg end) t)))
- (w1 (- end beg))
- (with-hm (and (nth 1 t1) (nth 2 t1)))
- (tf (funcall (if with-hm 'cdr 'car) org-time-stamp-custom-formats))
- (time (org-fix-decoded-time t1))
- (str (org-add-props
+ (let* ((ts (buffer-substring beg end))
+ t1 w1 with-hm tf time str w2 (off 0))
+ (save-match-data
+ (setq t1 (org-parse-time-string ts t))
+ (if (string-match "\\(-[0-9]+:[0-9]+\\)?\\( [.+]?\\+[0-9]+[dwmy]\\)?\\'" ts)
+ (setq off (- (match-end 0) (match-beginning 0)))))
+ (setq end (- end off))
+ (setq w1 (- end beg)
+ with-hm (and (nth 1 t1) (nth 2 t1))
+ tf (funcall (if with-hm 'cdr 'car) org-time-stamp-custom-formats)
+ time (org-fix-decoded-time t1)
+ str (org-add-props
(format-time-string
(substring tf 1 -1) (apply 'encode-time time))
- nil 'mouse-face 'highlight))
- (w2 (length str)))
+ nil 'mouse-face 'highlight)
+ w2 (length str))
(if (not (= w2 w1))
(add-text-properties (1+ beg) (+ 2 beg)
(list 'org-dwidth t 'org-dwidth-n (- w1 w2))))
(defun org-deadline-close (timestamp-string &optional ndays)
"Is the time in TIMESTAMP-STRING close to the current date?"
- (and (< (org-days-to-time timestamp-string)
- (or ndays org-deadline-warning-days))
+ (setq ndays (or ndays (org-get-wdays timestamp-string)))
+ (and (< (org-days-to-time timestamp-string) ndays)
(not (org-entry-is-done-p))))
+(defun org-get-wdays (ts)
+ "Get the deadline lead time appropriate for timestring TS."
+ (cond
+ ((<= org-deadline-warning-days 0)
+ ;; 0 or negative, enforce this value no matter what
+ (- org-deadline-warning-days))
+ ((string-match "-\\([0-9]+\\)\\([dwmy]\\)\\(\\'\\|>\\)" ts)
+ ;; lead time is specified.
+ (floor (* (string-to-number (match-string 1 ts))
+ (cdr (assoc (match-string 2 ts)
+ '(("d" . 1) ("w" . 7)
+ ("m" . 30.4) ("y" . 365.25)))))))
+ ;; go for the default.
+ (t org-deadline-warning-days)))
+
(defun org-calendar-select-mouse (ev)
"Return to `org-read-date' with the date currently selected.
This is used by `org-read-date' in a temporary keymap for the calendar buffer."
(cond
((equal ndays '(4)) 100000)
(ndays (prefix-numeric-value ndays))
- (t org-deadline-warning-days)))
+ (t (abs org-deadline-warning-days))))
(case-fold-search nil)
(regexp (concat "\\<" org-deadline-string " *<\\([^>]+\\)>"))
(callback
(org-occur regexp nil callback)
org-warn-days)))
+(defun org-check-before-date (date)
+ "Check if there are deadlines or scheduled entries before DATE."
+ (interactive (list (org-read-date)))
+ (let ((case-fold-search nil)
+ (regexp (concat "\\<\\(" org-deadline-string
+ "\\|" org-scheduled-string
+ "\\) *<\\([^>]+\\)>"))
+ (callback
+ (lambda () (time-less-p
+ (org-time-string-to-time (match-string 2))
+ (org-time-string-to-time date)))))
+ (message "%d entries before %s"
+ (org-occur regexp nil callback) date)))
+
(defun org-evaluate-time-range (&optional to-buffer)
"Evaluate a time range by computing the difference between start and end.
Normally the result is just printed in the echo area, but with prefix arg
(or
(org-clock-update-time-maybe)
(save-excursion
- (unless (org-at-date-range-p)
+ (unless (org-at-date-range-p t)
(goto-char (point-at-bol))
- (re-search-forward org-tr-regexp (point-at-eol) t))
- (if (not (org-at-date-range-p))
+ (re-search-forward org-tr-regexp-both (point-at-eol) t))
+ (if (not (org-at-date-range-p t))
(error "Not at a time-stamp range, and none found in current line")))
(let* ((ts1 (match-string 1))
(ts2 (match-string 2))
d (floor (+ (/ diff ds) 0.5))
h 0 m 0))
(if (not to-buffer)
- (message (org-make-tdiff-string y d h m))
- (when (org-at-table-p)
- (goto-char match-end)
- (setq align t)
- (and (looking-at " *|") (goto-char (match-end 0))))
+ (message "%s" (org-make-tdiff-string y d h m))
+ (if (org-at-table-p)
+ (progn
+ (goto-char match-end)
+ (setq align t)
+ (and (looking-at " *|") (goto-char (match-end 0))))
+ (goto-char match-end))
(if (looking-at
"\\( *-? *[0-9]+y\\)?\\( *[0-9]+d\\)? *[0-9][0-9]:[0-9][0-9]")
(replace-match ""))
(defun org-time-string-to-time (s)
(apply 'encode-time (org-parse-time-string s)))
+(defun org-time-string-to-absolute (s &optional daynr prefer)
+ "Convert a time stamp to an absolute day number.
+If there is a specifyer for a cyclic time stamp, get the closest date to
+DAYNR."
+ (cond
+ ((and daynr (string-match "\\`%%\\((.*)\\)" s))
+ (if (org-diary-sexp-entry (match-string 1 s) "" date)
+ daynr
+ (+ daynr 1000)))
+ ((and daynr (string-match "\\+[0-9]+[dwmy]" s))
+ (org-closest-date s (if (and (boundp 'daynr) (integerp daynr)) daynr
+ (time-to-days (current-time))) (match-string 0 s)
+ prefer))
+ (t (time-to-days (apply 'encode-time (org-parse-time-string s))))))
+
+(defun org-time-from-absolute (d)
+ "Return the time corresponding to date D.
+D may be an absolute day number, or a calendar-type list (month day year)."
+ (if (numberp d) (setq d (calendar-gregorian-from-absolute d)))
+ (encode-time 0 0 0 (nth 1 d) (car d) (nth 2 d)))
+
+(defun org-calendar-holiday ()
+ "List of holidays, for Diary display in Org-mode."
+ (require 'holidays)
+ (let ((hl (funcall
+ (if (fboundp 'calendar-check-holidays)
+ 'calendar-check-holidays 'check-calendar-holidays) date)))
+ (if hl (mapconcat 'identity hl "; "))))
+
+(defun org-diary-sexp-entry (sexp entry date)
+ "Process a SEXP diary ENTRY for DATE."
+ (require 'diary-lib)
+ (let ((result (if calendar-debug-sexp
+ (let ((stack-trace-on-error t))
+ (eval (car (read-from-string sexp))))
+ (condition-case nil
+ (eval (car (read-from-string sexp)))
+ (error
+ (beep)
+ (message "Bad sexp at line %d in %s: %s"
+ (org-current-line)
+ (buffer-file-name) sexp)
+ (sleep-for 2))))))
+ (cond ((stringp result) result)
+ ((and (consp result)
+ (stringp (cdr result))) (cdr result))
+ (result entry)
+ (t nil))))
+
+(defun org-diary-to-ical-string (frombuf)
+ "Get iCalendar entries from diary entries in buffer FROMBUF.
+This uses the icalendar.el library."
+ (let* ((tmpdir (if (featurep 'xemacs)
+ (temp-directory)
+ temporary-file-directory))
+ (tmpfile (make-temp-name
+ (expand-file-name "orgics" tmpdir)))
+ buf rtn b e)
+ (save-excursion
+ (set-buffer frombuf)
+ (icalendar-export-region (point-min) (point-max) tmpfile)
+ (setq buf (find-buffer-visiting tmpfile))
+ (set-buffer buf)
+ (goto-char (point-min))
+ (if (re-search-forward "^BEGIN:VEVENT" nil t)
+ (setq b (match-beginning 0)))
+ (goto-char (point-max))
+ (if (re-search-backward "^END:VEVENT" nil t)
+ (setq e (match-end 0)))
+ (setq rtn (if (and b e) (concat (buffer-substring b e) "\n") "")))
+ (kill-buffer buf)
+ (kill-buffer frombuf)
+ (delete-file tmpfile)
+ rtn))
+
+(defun org-closest-date (start current change prefer)
+ "Find the date closest to CURRENT that is consistent with START and CHANGE.
+When PREFER is `past' return a date that is either CURRENT or past.
+When PREFER is `future', return a date that is either CURRENT or future."
+ ;; Make the proper lists from the dates
+ (catch 'exit
+ (let ((a1 '(("d" . day) ("w" . week) ("m" . month) ("y" . year)))
+ dn dw sday cday n1 n2
+ d m y y1 y2 date1 date2 nmonths nm ny m2)
+
+ (setq start (org-date-to-gregorian start)
+ current (org-date-to-gregorian
+ (if org-agenda-repeating-timestamp-show-all
+ current
+ (time-to-days (current-time))))
+ sday (calendar-absolute-from-gregorian start)
+ cday (calendar-absolute-from-gregorian current))
+
+ (if (<= cday sday) (throw 'exit sday))
+
+ (if (string-match "\\(\\+[0-9]+\\)\\([dwmy]\\)" change)
+ (setq dn (string-to-number (match-string 1 change))
+ dw (cdr (assoc (match-string 2 change) a1)))
+ (error "Invalid change specifyer: %s" change))
+ (if (eq dw 'week) (setq dw 'day dn (* 7 dn)))
+ (cond
+ ((eq dw 'day)
+ (setq n1 (+ sday (* dn (floor (/ (- cday sday) dn))))
+ n2 (+ n1 dn)))
+ ((eq dw 'year)
+ (setq d (nth 1 start) m (car start) y1 (nth 2 start) y2 (nth 2 current))
+ (setq y1 (+ (* (floor (/ (- y2 y1) dn)) dn) y1))
+ (setq date1 (list m d y1)
+ n1 (calendar-absolute-from-gregorian date1)
+ date2 (list m d (+ y1 (* (if (< n1 cday) 1 -1) dn)))
+ n2 (calendar-absolute-from-gregorian date2)))
+ ((eq dw 'month)
+ ;; approx number of month between the tow dates
+ (setq nmonths (floor (/ (- cday sday) 30.436875)))
+ ;; How often does dn fit in there?
+ (setq d (nth 1 start) m (car start) y (nth 2 start)
+ nm (* dn (max 0 (1- (floor (/ nmonths dn)))))
+ m (+ m nm)
+ ny (floor (/ m 12))
+ y (+ y ny)
+ m (- m (* ny 12)))
+ (while (> m 12) (setq m (- m 12) y (1+ y)))
+ (setq n1 (calendar-absolute-from-gregorian (list m d y)))
+ (setq m2 (+ m dn) y2 y)
+ (if (> m2 12) (setq y2 (1+ y2) m2 (- m2 12)))
+ (setq n2 (calendar-absolute-from-gregorian (list m2 d y2)))
+ (while (< n2 cday)
+ (setq n1 n2 m m2 y y2)
+ (setq m2 (+ m dn) y2 y)
+ (if (> m2 12) (setq y2 (1+ y2) m2 (- m2 12)))
+ (setq n2 (calendar-absolute-from-gregorian (list m2 d y2))))))
+
+ (if org-agenda-repeating-timestamp-show-all
+ (cond
+ ((eq prefer 'past) n1)
+ ((eq prefer 'future) (if (= cday n1) n1 n2))
+ (t (if (> (abs (- cday n1)) (abs (- cday n2))) n2 n1)))
+ (cond
+ ((eq prefer 'past) n1)
+ ((eq prefer 'future) (if (= cday n1) n1 n2))
+ (t (if (= cday n1) n1 n2)))))))
+
+(defun org-date-to-gregorian (date)
+ "Turn any specification of DATE into a gregorian date for the calendar."
+ (cond ((integerp date) (calendar-gregorian-from-absolute date))
+ ((and (listp date) (= (length date) 3)) date)
+ ((stringp date)
+ (setq date (org-parse-time-string date))
+ (list (nth 4 date) (nth 3 date) (nth 5 date)))
+ ((listp date)
+ (list (nth 4 date) (nth 3 date) (nth 5 date)))))
+
(defun org-parse-time-string (s &optional nodefault)
"Parse the standard Org-mode time string.
This should be a lot faster than the normal `parse-time-string'.
If time is not given, defaults to 0:00. However, with optional NODEFAULT,
hour and minute fields will be nil if not given."
- (if (string-match org-ts-regexp1 s)
+ (if (string-match org-ts-regexp0 s)
(list 0
(if (or (match-beginning 8) (not nodefault))
(string-to-number (or (match-string 8 s) "0")))
(ans (or (looking-at tsr)
(save-excursion
(skip-chars-backward "^[<\n\r\t")
- (if (> (point) 1) (backward-char 1))
+ (if (> (point) (point-min)) (backward-char 1))
(and (looking-at tsr)
(> (- (match-end 0) pos) -1))))))
- (and (boundp 'org-ts-what)
+ (and ans
+ (boundp 'org-ts-what)
(setq org-ts-what
(cond
+ ((= pos (match-beginning 0)) 'bracket)
+ ((= pos (1- (match-end 0))) 'bracket)
((org-pos-in-match-range pos 2) 'year)
((org-pos-in-match-range pos 3) 'month)
((org-pos-in-match-range pos 7) 'hour)
((org-pos-in-match-range pos 8) 'minute)
((or (org-pos-in-match-range pos 4)
(org-pos-in-match-range pos 5)) 'day)
+ ((and (> pos (or (match-end 8) (match-end 5)))
+ (< pos (match-end 0)))
+ (- pos (or (match-end 8) (match-end 5))))
(t 'day))))
ans))
+(defun org-toggle-timestamp-type ()
+ "Toggle the type (<active> or [inactive]) of a time stamp."
+ (interactive)
+ (when (org-at-timestamp-p t)
+ (save-excursion
+ (goto-char (match-beginning 0))
+ (insert (if (equal (char-after) ?<) "[" "<")) (delete-char 1)
+ (goto-char (1- (match-end 0)))
+ (insert (if (equal (char-after) ?>) "]" ">")) (delete-char 1))
+ (message "Timestamp is now %sactive"
+ (if (equal (char-before) ?>) "in" ""))))
+
(defun org-timestamp-change (n &optional what)
"Change the date in the time stamp at point.
The date will be changed by N times WHAT. WHAT can be `day', `month',
in the timestamp determines what will be changed."
(let ((pos (point))
with-hm inactive
+ (dm (max (nth 1 org-time-stamp-rounding-minutes) 1))
org-ts-what
+ extra rem
ts time time0)
(if (not (org-at-timestamp-p t))
(error "Not at a timestamp"))
- (if (and (not what) (not (eq org-ts-what 'day))
- org-display-custom-times
- (get-text-property (point) 'display)
- (not (get-text-property (1- (point)) 'display)))
- (setq org-ts-what 'day))
- (setq org-ts-what (or what org-ts-what)
- with-hm (<= (abs (- (cdr org-ts-lengths)
- (- (match-end 0) (match-beginning 0))))
- 1)
- inactive (= (char-after (match-beginning 0)) ?\[)
- ts (match-string 0))
- (replace-match "")
- (setq time0 (org-parse-time-string ts))
- (setq time
- (apply 'encode-time
- (append
- (list (or (car time0) 0))
- (list (+ (if (eq org-ts-what 'minute) n 0) (nth 1 time0)))
- (list (+ (if (eq org-ts-what 'hour) n 0) (nth 2 time0)))
- (list (+ (if (eq org-ts-what 'day) n 0) (nth 3 time0)))
- (list (+ (if (eq org-ts-what 'month) n 0) (nth 4 time0)))
- (list (+ (if (eq org-ts-what 'year) n 0) (nth 5 time0)))
- (nthcdr 6 time0))))
- (if (eq what 'calendar)
- (let ((cal-date
- (save-excursion
- (save-match-data
- (set-buffer "*Calendar*")
- (calendar-cursor-to-date)))))
- (setcar (nthcdr 4 time0) (nth 0 cal-date)) ; month
- (setcar (nthcdr 3 time0) (nth 1 cal-date)) ; day
- (setcar (nthcdr 5 time0) (nth 2 cal-date)) ; year
- (setcar time0 (or (car time0) 0))
- (setcar (nthcdr 1 time0) (or (nth 1 time0) 0))
- (setcar (nthcdr 2 time0) (or (nth 1 time0) 0))
- (setq time (apply 'encode-time time0))))
- (setq org-last-changed-timestamp
- (org-insert-time-stamp time with-hm inactive))
- (org-clock-update-time-maybe)
- (goto-char pos)
- ;; Try to recenter the calendar window, if any
- (if (and org-calendar-follow-timestamp-change
- (get-buffer-window "*Calendar*" t)
- (memq org-ts-what '(day month year)))
- (org-recenter-calendar (time-to-days time)))))
+ (if (and (not what) (eq org-ts-what 'bracket))
+ (org-toggle-timestamp-type)
+ (if (and (not what) (not (eq org-ts-what 'day))
+ org-display-custom-times
+ (get-text-property (point) 'display)
+ (not (get-text-property (1- (point)) 'display)))
+ (setq org-ts-what 'day))
+ (setq org-ts-what (or what org-ts-what)
+ inactive (= (char-after (match-beginning 0)) ?\[)
+ ts (match-string 0))
+ (replace-match "")
+ (if (string-match
+ "\\(\\(-[012][0-9]:[0-5][0-9]\\)?\\( +[.+]?[-+][0-9]+[dwmy]\\)*\\)[]>]"
+ ts)
+ (setq extra (match-string 1 ts)))
+ (if (string-match "^.\\{10\\}.*?[0-9]+:[0-9][0-9]" ts)
+ (setq with-hm t))
+ (setq time0 (org-parse-time-string ts))
+ (when (and (eq org-ts-what 'minute)
+ (eq current-prefix-arg nil))
+ (setq n (* dm (org-no-warnings (signum n))))
+ (when (not (= 0 (setq rem (% (nth 1 time0) dm))))
+ (setcar (cdr time0) (+ (nth 1 time0)
+ (if (> n 0) (- rem) (- dm rem))))))
+ (setq time
+ (encode-time (or (car time0) 0)
+ (+ (if (eq org-ts-what 'minute) n 0) (nth 1 time0))
+ (+ (if (eq org-ts-what 'hour) n 0) (nth 2 time0))
+ (+ (if (eq org-ts-what 'day) n 0) (nth 3 time0))
+ (+ (if (eq org-ts-what 'month) n 0) (nth 4 time0))
+ (+ (if (eq org-ts-what 'year) n 0) (nth 5 time0))
+ (nthcdr 6 time0)))
+ (when (integerp org-ts-what)
+ (setq extra (org-modify-ts-extra extra org-ts-what n dm)))
+ (if (eq what 'calendar)
+ (let ((cal-date (org-get-date-from-calendar)))
+ (setcar (nthcdr 4 time0) (nth 0 cal-date)) ; month
+ (setcar (nthcdr 3 time0) (nth 1 cal-date)) ; day
+ (setcar (nthcdr 5 time0) (nth 2 cal-date)) ; year
+ (setcar time0 (or (car time0) 0))
+ (setcar (nthcdr 1 time0) (or (nth 1 time0) 0))
+ (setcar (nthcdr 2 time0) (or (nth 2 time0) 0))
+ (setq time (apply 'encode-time time0))))
+ (setq org-last-changed-timestamp
+ (org-insert-time-stamp time with-hm inactive nil nil extra))
+ (org-clock-update-time-maybe)
+ (goto-char pos)
+ ;; Try to recenter the calendar window, if any
+ (if (and org-calendar-follow-timestamp-change
+ (get-buffer-window "*Calendar*" t)
+ (memq org-ts-what '(day month year)))
+ (org-recenter-calendar (time-to-days time))))))
+
+;; FIXME: does not yet work for lead times
+(defun org-modify-ts-extra (s pos n dm)
+ "Change the different parts of the lead-time and repeat fields in timestamp."
+ (let ((idx '(("d" . 0) ("w" . 1) ("m" . 2) ("y" . 3) ("d" . -1) ("y" . 4)))
+ ng h m new rem)
+ (when (string-match "\\(-\\([012][0-9]\\):\\([0-5][0-9]\\)\\)?\\( +\\+\\([0-9]+\\)\\([dmwy]\\)\\)?\\( +-\\([0-9]+\\)\\([dmwy]\\)\\)?" s)
+ (cond
+ ((or (org-pos-in-match-range pos 2)
+ (org-pos-in-match-range pos 3))
+ (setq m (string-to-number (match-string 3 s))
+ h (string-to-number (match-string 2 s)))
+ (if (org-pos-in-match-range pos 2)
+ (setq h (+ h n))
+ (setq n (* dm (org-no-warnings (signum n))))
+ (when (not (= 0 (setq rem (% m dm))))
+ (setq m (+ m (if (> n 0) (- rem) (- dm rem)))))
+ (setq m (+ m n)))
+ (if (< m 0) (setq m (+ m 60) h (1- h)))
+ (if (> m 59) (setq m (- m 60) h (1+ h)))
+ (setq h (min 24 (max 0 h)))
+ (setq ng 1 new (format "-%02d:%02d" h m)))
+ ((org-pos-in-match-range pos 6)
+ (setq ng 6 new (car (rassoc (+ n (cdr (assoc (match-string 6 s) idx))) idx))))
+ ((org-pos-in-match-range pos 5)
+ (setq ng 5 new (format "%d" (max 1 (+ n (string-to-number (match-string 5 s)))))))
+
+ ((org-pos-in-match-range pos 9)
+ (setq ng 9 new (car (rassoc (+ n (cdr (assoc (match-string 9 s) idx))) idx))))
+ ((org-pos-in-match-range pos 8)
+ (setq ng 8 new (format "%d" (max 0 (+ n (string-to-number (match-string 8 s))))))))
+
+ (when ng
+ (setq s (concat
+ (substring s 0 (match-beginning ng))
+ new
+ (substring s (match-end ng))))))
+ s))
(defun org-recenter-calendar (date)
"If the calendar is visible, recenter it to DATE."
(interactive "P")
(let ((tsr org-ts-regexp) diff
(calendar-move-hook nil)
+ (calendar-view-holidays-initially-flag nil)
(view-calendar-holidays-initially nil)
+ (calendar-view-diary-initially-flag nil)
(view-diary-entries-initially nil))
(if (or (org-at-timestamp-p)
(save-excursion
(calendar-goto-today)
(if (and diff (not arg)) (calendar-forward-day diff))))
+(defun org-get-date-from-calendar ()
+ "Return a list (month day year) of date at point in calendar."
+ (with-current-buffer "*Calendar*"
+ (save-match-data
+ (calendar-cursor-to-date))))
+
(defun org-date-from-calendar ()
"Insert time stamp corresponding to cursor date in *Calendar* buffer.
If there is already a time stamp at the cursor position, update it."
(interactive)
- (org-timestamp-change 0 'calendar))
+ (if (org-at-timestamp-p t)
+ (org-timestamp-change 0 'calendar)
+ (let ((cal-date (org-get-date-from-calendar)))
+ (org-insert-time-stamp
+ (encode-time 0 0 0 (nth 1 cal-date) (car cal-date) (nth 2 cal-date))))))
+
+(defvar appt-time-msg-list)
+
+;;;###autoload
+(defun org-agenda-to-appt (&optional refresh filter)
+ "Activate appointments found in `org-agenda-files'.
+With a \\[universal-argument] prefix, refresh the list of
+appointements.
+
+If FILTER is t, interactively prompt the user for a regular
+expression, and filter out entries that don't match it.
+
+If FILTER is a string, use this string as a regular expression
+for filtering entries out.
+
+FILTER can also be an alist with the car of each cell being
+either 'headline or 'category. For example:
+
+ '((headline \"IMPORTANT\")
+ (category \"Work\"))
+
+will only add headlines containing IMPORTANT or headlines
+belonging to the \"Work\" category."
+ (interactive "P")
+ (require 'calendar)
+ (if refresh (setq appt-time-msg-list nil))
+ (if (eq filter t)
+ (setq filter (read-from-minibuffer "Regexp filter: ")))
+ (let* ((cnt 0) ; count added events
+ (org-agenda-new-buffers nil)
+ (org-deadline-warning-days 0)
+ (today (org-date-to-gregorian
+ (time-to-days (current-time))))
+ (files (org-agenda-files)) entries file)
+ ;; Get all entries which may contain an appt
+ (while (setq file (pop files))
+ (setq entries
+ (append entries
+ (org-agenda-get-day-entries
+ file today :timestamp :scheduled :deadline))))
+ (setq entries (delq nil entries))
+ ;; Map thru entries and find if we should filter them out
+ (mapc
+ (lambda(x)
+ (let* ((evt (org-trim (get-text-property 1 'txt x)))
+ (cat (get-text-property 1 'org-category x))
+ (tod (get-text-property 1 'time-of-day x))
+ (ok (or (null filter)
+ (and (stringp filter) (string-match filter evt))
+ (and (listp filter)
+ (or (string-match
+ (cadr (assoc 'category filter)) cat)
+ (string-match
+ (cadr (assoc 'headline filter)) evt))))))
+ ;; FIXME: Shall we remove text-properties for the appt text?
+ ;; (setq evt (set-text-properties 0 (length evt) nil evt))
+ (when (and ok tod)
+ (setq tod (number-to-string tod)
+ tod (when (string-match
+ "\\([0-9]\\{1,2\\}\\)\\([0-9]\\{2\\}\\)" tod)
+ (concat (match-string 1 tod) ":"
+ (match-string 2 tod))))
+ (appt-add tod evt)
+ (setq cnt (1+ cnt))))) entries)
+ (org-release-buffers org-agenda-new-buffers)
+ (if (eq cnt 0)
+ (message "No event to add")
+ (message "Added %d event%s for today" cnt (if (> cnt 1) "s" "")))))
+
+;;; The clock for measuring work time.
+
+(defvar org-mode-line-string "")
+(put 'org-mode-line-string 'risky-local-variable t)
+
+(defvar org-mode-line-timer nil)
+(defvar org-clock-heading "")
+(defvar org-clock-start-time "")
-;;; The clock for measuring work time.
+(defun org-update-mode-line ()
+ (let* ((delta (- (time-to-seconds (current-time))
+ (time-to-seconds org-clock-start-time)))
+ (h (floor delta 3600))
+ (m (floor (- delta (* 3600 h)) 60)))
+ (setq org-mode-line-string
+ (propertize (format "-[%d:%02d (%s)]" h m org-clock-heading)
+ 'help-echo "Org-mode clock is running"))
+ (force-mode-line-update)))
(defvar org-clock-marker (make-marker)
"Marker recording the last clock-in.")
+(defvar org-clock-mode-line-entry nil
+ "Information for the modeline about the running clock.")
(defun org-clock-in ()
"Start the clock on the current item.
(let (ts)
(save-excursion
(org-back-to-heading t)
- (beginning-of-line 2)
- (when (and (looking-at (concat "[ \t]*" org-keyword-time-regexp))
- (not (equal (match-string 1) org-clock-string)))
- ;; First line hast scheduling info, move one further
- (beginning-of-line 2)
- (or (bolp) (newline)))
+ (when (and org-clock-in-switch-to-state
+ (not (looking-at (concat outline-regexp "[ \t]*"
+ org-clock-in-switch-to-state
+ "\\>"))))
+ (org-todo org-clock-in-switch-to-state))
+ (if (and org-clock-heading-function
+ (functionp org-clock-heading-function))
+ (setq org-clock-heading (funcall org-clock-heading-function))
+ (if (looking-at org-complex-heading-regexp)
+ (setq org-clock-heading (match-string 4))
+ (setq org-clock-heading "???")))
+ (setq org-clock-heading (propertize org-clock-heading 'face nil))
+ (org-clock-find-position)
+
(insert "\n") (backward-char 1)
(indent-relative)
(insert org-clock-string " ")
+ (setq org-clock-start-time (current-time))
(setq ts (org-insert-time-stamp (current-time) 'with-hm 'inactive))
(move-marker org-clock-marker (point) (buffer-base-buffer))
+ (or global-mode-string (setq global-mode-string '("")))
+ (or (memq 'org-mode-line-string global-mode-string)
+ (setq global-mode-string
+ (append global-mode-string '(org-mode-line-string))))
+ (org-update-mode-line)
+ (setq org-mode-line-timer (run-with-timer 60 60 'org-update-mode-line))
(message "Clock started at %s" ts))))
+(defun org-clock-find-position ()
+ "Find the location where the next clock line should be inserted."
+ (org-back-to-heading t)
+ (catch 'exit
+ (let ((beg (point-at-bol 2)) (end (progn (outline-next-heading) (point)))
+ (re (concat "^[ \t]*" org-clock-string))
+ (cnt 0)
+ first last)
+ (goto-char beg)
+ (when (eobp) (newline) (setq end (max (point) end)))
+ (when (re-search-forward "^[ \t]*:CLOCK:" end t)
+ ;; we seem to have a CLOCK drawer, so go there.
+ (beginning-of-line 2)
+ (throw 'exit t))
+ ;; Lets count the CLOCK lines
+ (goto-char beg)
+ (while (re-search-forward re end t)
+ (setq first (or first (match-beginning 0))
+ last (match-beginning 0)
+ cnt (1+ cnt)))
+ (when (and (integerp org-clock-into-drawer)
+ (>= (1+ cnt) org-clock-into-drawer))
+ ;; Wrap current entries into a new drawer
+ (goto-char last)
+ (beginning-of-line 2)
+ (if (org-at-item-p) (org-end-of-item))
+ (insert ":END:\n")
+ (beginning-of-line 0)
+ (org-indent-line-function)
+ (goto-char first)
+ (insert ":CLOCK:\n")
+ (beginning-of-line 0)
+ (org-indent-line-function)
+ (org-flag-drawer t)
+ (beginning-of-line 2)
+ (throw 'exit nil))
+
+ (goto-char beg)
+ (while (and (looking-at (concat "[ \t]*" org-keyword-time-regexp))
+ (not (equal (match-string 1) org-clock-string)))
+ ;; Planning info, skip to after it
+ (beginning-of-line 2)
+ (or (bolp) (newline)))
+ (when (eq t org-clock-into-drawer)
+ (insert ":CLOCK:\n:END:\n")
+ (beginning-of-line -1)
+ (org-indent-line-function)
+ (org-flag-drawer t)
+ (beginning-of-line 2)
+ (org-indent-line-function)))))
+
(defun org-clock-out (&optional fail-quietly)
"Stop the currently running clock.
If there is no running clock, throw an error, unless FAIL-QUIETLY is set."
(equal (match-string 1) org-clock-string))
(setq ts (match-string 2))
(if fail-quietly (throw 'exit nil) (error "Clock start time is gone")))
- (goto-char org-clock-marker)
+ (goto-char (match-end 0))
+ (delete-region (point) (point-at-eol))
(insert "--")
(setq te (org-insert-time-stamp (current-time) 'with-hm 'inactive))
(setq s (- (time-to-seconds (apply 'encode-time (org-parse-time-string te)))
s (- s (* 60 s)))
(insert " => " (format "%2d:%02d" h m))
(move-marker org-clock-marker nil)
- (org-add-log-maybe 'clock-out)
+ (when org-log-note-clock-out
+ (org-add-log-maybe 'clock-out))
+ (when org-mode-line-timer
+ (cancel-timer org-mode-line-timer)
+ (setq org-mode-line-timer nil))
+ (setq global-mode-string
+ (delq 'org-mode-line-string global-mode-string))
+ (force-mode-line-update)
(message "Clock stopped at %s after HH:MM = %d:%02d" te h m)))))
(defun org-clock-cancel ()
(set-buffer (marker-buffer org-clock-marker))
(goto-char org-clock-marker)
(delete-region (1- (point-at-bol)) (point-at-eol)))
+ (setq global-mode-string
+ (delq 'org-mode-line-string global-mode-string))
+ (force-mode-line-update)
(message "Clock canceled"))
+(defun org-clock-goto (&optional delete-windows)
+ "Go to the currently clocked-in entry."
+ (interactive "P")
+ (if (not (marker-buffer org-clock-marker))
+ (error "No active clock"))
+ (switch-to-buffer-other-window
+ (marker-buffer org-clock-marker))
+ (if delete-windows (delete-other-windows))
+ (goto-char org-clock-marker)
+ (org-show-entry)
+ (org-back-to-heading)
+ (recenter))
+
(defvar org-clock-file-total-minutes nil
"Holds the file total time in minutes, after a call to `org-clock-sum'.")
(make-variable-buffer-local 'org-clock-file-total-minutes)
(let* ((bmp (buffer-modified-p))
(re (concat "^\\(\\*+\\)[ \t]\\|^[ \t]*"
org-clock-string
- "[ \t]*\\(\\[.*?\\]\\)-+\\(\\[.*?\\]\\)"))
+ "[ \t]*\\(?:\\(\\[.*?\\]\\)-+\\(\\[.*?\\]\\)\\|=>[ \t]+\\([0-9]+\\):\\([0-9]+\\)\\)"))
(lmax 30)
(ltimes (make-vector lmax 0))
(t1 0)
(save-excursion
(goto-char (point-max))
(while (re-search-backward re nil t)
- (if (match-end 2)
- ;; A time
- (setq ts (match-string 2)
- te (match-string 3)
- ts (time-to-seconds
- (apply 'encode-time (org-parse-time-string ts)))
- te (time-to-seconds
- (apply 'encode-time (org-parse-time-string te)))
- ts (if tstart (max ts tstart) ts)
- te (if tend (min te tend) te)
- dt (- te ts)
- t1 (if (> dt 0) (+ t1 (floor (/ dt 60))) t1))
- ;; A headline
+ (cond
+ ((match-end 2)
+ ;; Two time stamps
+ (setq ts (match-string 2)
+ te (match-string 3)
+ ts (time-to-seconds
+ (apply 'encode-time (org-parse-time-string ts)))
+ te (time-to-seconds
+ (apply 'encode-time (org-parse-time-string te)))
+ ts (if tstart (max ts tstart) ts)
+ te (if tend (min te tend) te)
+ dt (- te ts)
+ t1 (if (> dt 0) (+ t1 (floor (/ dt 60))) t1)))
+ ((match-end 4)
+ ;; A naket time
+ (setq t1 (+ t1 (string-to-number (match-string 5))
+ (* 60 (string-to-number (match-string 4))))))
+ (t ;; A headline
(setq level (- (match-end 1) (match-beginning 1)))
(when (or (> t1 0) (> (aref ltimes level) 0))
(loop for l from 0 to level do
(loop for l from level to (1- lmax) do
(aset ltimes l 0))
(goto-char (match-beginning 0))
- (put-text-property (point) (point-at-eol) :org-clock-minutes time))))
+ (put-text-property (point) (point-at-eol) :org-clock-minutes time)))))
(setq org-clock-file-total-minutes (aref ltimes 0)))
(set-buffer-modified-p bmp)))
(unless total-only
(save-excursion
(goto-char (point-min))
- (while (setq p (next-single-property-change (point) :org-clock-minutes))
+ (while (or (and (equal (setq p (point)) (point-min))
+ (get-text-property p :org-clock-minutes))
+ (setq p (next-single-property-change
+ (point) :org-clock-minutes)))
(goto-char p)
(when (setq time (get-text-property p :org-clock-minutes))
(org-put-clock-overlay time (funcall outline-level))))
This creates a new overlay and stores it in `org-clock-overlays', so that it
will be easy to remove."
(let* ((c 60) (h (floor (/ time 60))) (m (- time (* 60 h)))
- (l (if level (org-get-legal-level level 0) 0))
+ (l (if level (org-get-valid-level level 0) 0))
(off 0)
ov tx)
(move-to-column c)
(make-string (+ off (max 0 (- c (current-column)))) ?.)
(org-add-props (format "%s %2d:%02d%s"
(make-string l ?*) h m
- (make-string (- 10 l) ?\ ))
+ (make-string (- 16 l) ?\ ))
'(face secondary-selection))
""))
(if (not (featurep 'xemacs))
(defun org-clock-out-if-current ()
"Clock out if the current entry contains the running clock.
-This is used to stop the clock after a TODO entry is marked DONE."
- (when (and (equal state org-done-string)
+This is used to stop the clock after a TODO entry is marked DONE,
+and is only done if the variable `org-clock-out-when-done' is not nil."
+ (when (and org-clock-out-when-done
+ (member state org-done-keywords)
(equal (marker-buffer org-clock-marker) (current-buffer))
(< (point) org-clock-marker)
(> (save-excursion (outline-next-heading) (point))
org-clock-marker))
;; Clock out, but don't accept a logging message for this.
- (let ((org-log-done (if (and (listp org-log-done)
- (member 'clock-out org-log-done))
- '(done)
- org-log-done)))
+ (let ((org-log-note-clock-out nil))
(org-clock-out))))
(add-hook 'org-after-todo-state-change-hook
(when (y-or-n-p "Save changed buffer?")
(save-buffer))))
-(defun org-clock-report ()
+(defun org-clock-report (&optional arg)
"Create a table containing a report about clocked time.
-If the buffer contains lines
-#+BEGIN: clocktable :maxlevel 3 :emphasize nil
-
-#+END: clocktable
-then the table will be inserted between these lines, replacing whatever
-is was there before. If these lines are not in the buffer, the table
-is inserted at point, surrounded by the special lines.
-The BEGIN line can contain parameters. Allowed are:
-:maxlevel The maximum level to be included in the table. Default is 3.
-:emphasize t/nil, if levell 1 and level 2 should be bold/italic in the table."
- (interactive)
+If the cursor is inside an existing clocktable block, then the table
+will be updated. If not, a new clocktable will be inserted.
+When called with a prefix argument, move to the first clock table in the
+buffer and update it."
+ (interactive "P")
(org-remove-clock-overlays)
- (unless (org-find-dblock "clocktable")
+ (when arg
+ (org-find-dblock "clocktable")
+ (org-show-entry))
+ (if (org-in-clocktable-p)
+ (goto-char (org-in-clocktable-p))
(org-create-dblock (list :name "clocktable"
- :maxlevel 2 :emphasize nil)))
+ :maxlevel 2 :scope 'file)))
(org-update-dblock))
+(defun org-in-clocktable-p ()
+ "Check if the cursor is in a clocktable."
+ (let ((pos (point)) start)
+ (save-excursion
+ (end-of-line 1)
+ (and (re-search-backward "^#\\+BEGIN:[ \t]+clocktable" nil t)
+ (setq start (match-beginning 0))
+ (re-search-forward "^#\\+END:.*" nil t)
+ (>= (match-end 0) pos)
+ start))))
+
(defun org-clock-update-time-maybe ()
"If this is a CLOCK line, update it and return t.
Otherwise, return nil."
(defun org-dblock-write:clocktable (params)
"Write the standard clocktable."
- (let ((hlchars '((1 . "*") (2 . ?/)))
- (emph nil)
- (ins (make-marker))
- ipos time h m p level hlc hdl maxlevel
- ts te cc block)
- (setq maxlevel (or (plist-get params :maxlevel) 3)
- emph (plist-get params :emphasize)
- ts (plist-get params :tstart)
- te (plist-get params :tend)
- block (plist-get params :block))
+ (catch 'exit
+ (let* ((hlchars '((1 . "*") (2 . "/")))
+ (ins (make-marker))
+ (total-time nil)
+ (scope (plist-get params :scope))
+ (tostring (plist-get params :tostring))
+ (multifile (plist-get params :multifile))
+ (header (plist-get params :header))
+ (maxlevel (or (plist-get params :maxlevel) 3))
+ (step (plist-get params :step))
+ (emph (plist-get params :emphasize))
+ (ts (plist-get params :tstart))
+ (te (plist-get params :tend))
+ (block (plist-get params :block))
+ (link (plist-get params :link))
+ ipos time h m p level hlc hdl
+ cc beg end pos tbl)
+ (when step
+ (org-clocktable-steps params)
+ (throw 'exit nil))
+ (when block
+ (setq cc (org-clock-special-range block nil t)
+ ts (car cc) te (cdr cc)))
+ (if ts (setq ts (time-to-seconds
+ (apply 'encode-time (org-parse-time-string ts)))))
+ (if te (setq te (time-to-seconds
+ (apply 'encode-time (org-parse-time-string te)))))
+ (move-marker ins (point))
+ (setq ipos (point))
+
+ ;; Get the right scope
+ (setq pos (point))
+ (save-restriction
+ (cond
+ ((not scope))
+ ((eq scope 'file) (widen))
+ ((eq scope 'subtree) (org-narrow-to-subtree))
+ ((eq scope 'tree)
+ (while (org-up-heading-safe))
+ (org-narrow-to-subtree))
+ ((and (symbolp scope) (string-match "^tree\\([0-9]+\\)$"
+ (symbol-name scope)))
+ (setq level (string-to-number (match-string 1 (symbol-name scope))))
+ (catch 'exit
+ (while (org-up-heading-safe)
+ (looking-at outline-regexp)
+ (if (<= (org-reduced-level (funcall outline-level)) level)
+ (throw 'exit nil))))
+ (org-narrow-to-subtree))
+ ((or (listp scope) (eq scope 'agenda))
+ (let* ((files (if (listp scope) scope (org-agenda-files)))
+ (scope 'agenda)
+ (p1 (copy-sequence params))
+ file)
+ (plist-put p1 :tostring t)
+ (plist-put p1 :multifile t)
+ (plist-put p1 :scope 'file)
+ (org-prepare-agenda-buffers files)
+ (while (setq file (pop files))
+ (with-current-buffer (find-buffer-visiting file)
+ (push (org-clocktable-add-file
+ file (org-dblock-write:clocktable p1)) tbl)
+ (setq total-time (+ (or total-time 0)
+ org-clock-file-total-minutes)))))))
+ (goto-char pos)
+
+ (unless (eq scope 'agenda)
+ (org-clock-sum ts te)
+ (goto-char (point-min))
+ (while (setq p (next-single-property-change (point) :org-clock-minutes))
+ (goto-char p)
+ (when (setq time (get-text-property p :org-clock-minutes))
+ (save-excursion
+ (beginning-of-line 1)
+ (when (and (looking-at (org-re "\\(\\*+\\)[ \t]+\\(.*?\\)\\([ \t]+:[[:alnum:]_@:]+:\\)?[ \t]*$"))
+ (setq level (org-reduced-level
+ (- (match-end 1) (match-beginning 1))))
+ (<= level maxlevel))
+ (setq hlc (if emph (or (cdr (assoc level hlchars)) "") "")
+ hdl (if (not link)
+ (match-string 2)
+ (org-make-link-string
+ (format "file:%s::%s"
+ (buffer-file-name)
+ (save-match-data
+ (org-make-org-heading-search-string
+ (match-string 2))))
+ (match-string 2)))
+ h (/ time 60)
+ m (- time (* 60 h)))
+ (if (and (not multifile) (= level 1)) (push "|-" tbl))
+ (push (concat
+ "| " (int-to-string level) "|" hlc hdl hlc " |"
+ (make-string (1- level) ?|)
+ hlc (format "%d:%02d" h m) hlc
+ " |") tbl))))))
+ (setq tbl (nreverse tbl))
+ (if tostring
+ (if tbl (mapconcat 'identity tbl "\n") nil)
+ (goto-char ins)
+ (insert-before-markers
+ (or header
+ (concat
+ "Clock summary at ["
+ (substring
+ (format-time-string (cdr org-time-stamp-formats))
+ 1 -1)
+ "]."
+ (if block
+ (format " Considered range is /%s/." block)
+ "")
+ "\n\n"))
+ (if (eq scope 'agenda) "|File" "")
+ "|L|Headline|Time|\n")
+ (setq total-time (or total-time org-clock-file-total-minutes)
+ h (/ total-time 60)
+ m (- total-time (* 60 h)))
+ (insert-before-markers
+ "|-\n|"
+ (if (eq scope 'agenda) "|" "")
+ "|"
+ "*Total time*| "
+ (format "*%d:%02d*" h m)
+ "|\n|-\n")
+ (setq tbl (delq nil tbl))
+ (if (and (stringp (car tbl)) (> (length (car tbl)) 1)
+ (equal (substring (car tbl) 0 2) "|-"))
+ (pop tbl))
+ (insert-before-markers (mapconcat
+ 'identity (delq nil tbl)
+ (if (eq scope 'agenda) "\n|-\n" "\n")))
+ (backward-delete-char 1)
+ (goto-char ipos)
+ (skip-chars-forward "^|")
+ (org-table-align))))))
+
+(defun org-clocktable-steps (params)
+ (let* ((p1 (copy-sequence params))
+ (ts (plist-get p1 :tstart))
+ (te (plist-get p1 :tend))
+ (step0 (plist-get p1 :step))
+ (step (cdr (assoc step0 '((day . 86400) (week . 604800)))))
+ (block (plist-get p1 :block))
+ cc)
(when block
(setq cc (org-clock-special-range block nil t)
ts (car cc) te (cdr cc)))
(apply 'encode-time (org-parse-time-string ts)))))
(if te (setq te (time-to-seconds
(apply 'encode-time (org-parse-time-string te)))))
- (move-marker ins (point))
- (setq ipos (point))
- (insert-before-markers "Clock summary at ["
- (substring
- (format-time-string (cdr org-time-stamp-formats))
- 1 -1)
- "]."
- (if block
- (format " Considered range is /%s/." block)
- "")
- "\n\n|L|Headline|Time|\n")
- (org-clock-sum ts te)
- (setq h (/ org-clock-file-total-minutes 60)
- m (- org-clock-file-total-minutes (* 60 h)))
- (insert-before-markers "|-\n|0|" "*Total file time*| "
- (format "*%d:%02d*" h m)
- "|\n")
- (goto-char (point-min))
- (while (setq p (next-single-property-change (point) :org-clock-minutes))
- (goto-char p)
- (when (setq time (get-text-property p :org-clock-minutes))
- (save-excursion
- (beginning-of-line 1)
- (when (and (looking-at "\\(\\*+\\)[ \t]+\\(.*?\\)\\([ \t]+:[0-9a-zA-Z_@:]+:\\)?[ \t]*$")
- (setq level (- (match-end 1) (match-beginning 1)))
- (<= level maxlevel))
- (setq hlc (if emph (or (cdr (assoc level hlchars)) "") "")
- hdl (match-string 2)
- h (/ time 60)
- m (- time (* 60 h)))
- (goto-char ins)
- (if (= level 1) (insert-before-markers "|-\n"))
- (insert-before-markers
- "| " (int-to-string level) "|" hlc hdl hlc " |"
- (make-string (1- level) ?|)
- hlc
- (format "%d:%02d" h m)
- hlc
- " |\n")))))
- (goto-char ins)
- (backward-delete-char 1)
- (goto-char ipos)
- (skip-chars-forward "^|")
- (org-table-align)))
+ (plist-put p1 :header "")
+ (plist-put p1 :step nil)
+ (plist-put p1 :block nil)
+ (while (< ts te)
+ (or (bolp) (insert "\n"))
+ (plist-put p1 :tstart (format-time-string
+ (car org-time-stamp-formats)
+ (seconds-to-time ts)))
+ (plist-put p1 :tend (format-time-string
+ (car org-time-stamp-formats)
+ (seconds-to-time (setq ts (+ ts step)))))
+ (insert "\n" (if (eq step0 'day) "Daily report: " "Weekly report starting on: ")
+ (plist-get p1 :tstart) "\n")
+ (org-dblock-write:clocktable p1)
+ (re-search-forward "#\\+END:")
+ (end-of-line 0))))
+
+
+(defun org-clocktable-add-file (file table)
+ (if table
+ (let ((lines (org-split-string table "\n"))
+ (ff (file-name-nondirectory file)))
+ (mapconcat 'identity
+ (mapcar (lambda (x)
+ (if (string-match org-table-dataline-regexp x)
+ (concat "|" ff x)
+ x))
+ lines)
+ "\n"))))
;; FIXME: I don't think anybody uses this, ask David
(defun org-collect-clock-time-entries ()
(defvar org-agenda-follow-mode nil)
(defvar org-agenda-show-log nil)
(defvar org-agenda-redo-command nil)
+(defvar org-agenda-query-string nil)
(defvar org-agenda-mode-hook nil)
(defvar org-agenda-type nil)
(defvar org-agenda-force-single-file nil)
(substitute-key-definition 'undo 'org-agenda-undo
org-agenda-mode-map global-map)
-(define-key org-agenda-mode-map "\C-i" 'org-agenda-goto)
-(define-key org-agenda-mode-map [(tab)] 'org-agenda-goto)
-(define-key org-agenda-mode-map "\C-m" 'org-agenda-switch-to)
-(define-key org-agenda-mode-map "\C-k" 'org-agenda-kill)
-(define-key org-agenda-mode-map "\C-c$" 'org-agenda-archive)
-(define-key org-agenda-mode-map "\C-c\C-x\C-s" 'org-agenda-archive)
-(define-key org-agenda-mode-map "$" 'org-agenda-archive)
-(define-key org-agenda-mode-map "\C-c\C-o" 'org-agenda-open-link)
-(define-key org-agenda-mode-map " " 'org-agenda-show)
-(define-key org-agenda-mode-map "\C-c\C-t" 'org-agenda-todo)
-(define-key org-agenda-mode-map "\C-c\C-xb" 'org-agenda-tree-to-indirect-buffer)
-(define-key org-agenda-mode-map "b" 'org-agenda-tree-to-indirect-buffer)
-(define-key org-agenda-mode-map "o" 'delete-other-windows)
-(define-key org-agenda-mode-map "L" 'org-agenda-recenter)
-(define-key org-agenda-mode-map "t" 'org-agenda-todo)
-(define-key org-agenda-mode-map "a" 'org-agenda-toggle-archive-tag)
-(define-key org-agenda-mode-map ":" 'org-agenda-set-tags)
-(define-key org-agenda-mode-map "." 'org-agenda-goto-today)
-(define-key org-agenda-mode-map "d" 'org-agenda-day-view)
-(define-key org-agenda-mode-map "w" 'org-agenda-week-view)
-(define-key org-agenda-mode-map (org-key 'S-right) 'org-agenda-date-later)
-(define-key org-agenda-mode-map (org-key 'S-left) 'org-agenda-date-earlier)
-(define-key org-agenda-mode-map [?\C-c ?\C-x (right)] 'org-agenda-date-later)
-(define-key org-agenda-mode-map [?\C-c ?\C-x (left)] 'org-agenda-date-earlier)
-
-(define-key org-agenda-mode-map ">" 'org-agenda-date-prompt)
-(define-key org-agenda-mode-map "\C-c\C-s" 'org-agenda-schedule)
-(define-key org-agenda-mode-map "\C-c\C-d" 'org-agenda-deadline)
+(org-defkey org-agenda-mode-map "\C-i" 'org-agenda-goto)
+(org-defkey org-agenda-mode-map [(tab)] 'org-agenda-goto)
+(org-defkey org-agenda-mode-map "\C-m" 'org-agenda-switch-to)
+(org-defkey org-agenda-mode-map "\C-k" 'org-agenda-kill)
+(org-defkey org-agenda-mode-map "\C-c$" 'org-agenda-archive)
+(org-defkey org-agenda-mode-map "\C-c\C-x\C-s" 'org-agenda-archive)
+(org-defkey org-agenda-mode-map "$" 'org-agenda-archive)
+(org-defkey org-agenda-mode-map "\C-c\C-o" 'org-agenda-open-link)
+(org-defkey org-agenda-mode-map " " 'org-agenda-show)
+(org-defkey org-agenda-mode-map "\C-c\C-t" 'org-agenda-todo)
+(org-defkey org-agenda-mode-map [(control shift right)] 'org-agenda-todo-nextset)
+(org-defkey org-agenda-mode-map [(control shift left)] 'org-agenda-todo-previousset)
+(org-defkey org-agenda-mode-map "\C-c\C-xb" 'org-agenda-tree-to-indirect-buffer)
+(org-defkey org-agenda-mode-map "b" 'org-agenda-tree-to-indirect-buffer)
+(org-defkey org-agenda-mode-map "o" 'delete-other-windows)
+(org-defkey org-agenda-mode-map "L" 'org-agenda-recenter)
+(org-defkey org-agenda-mode-map "t" 'org-agenda-todo)
+(org-defkey org-agenda-mode-map "a" 'org-agenda-toggle-archive-tag)
+(org-defkey org-agenda-mode-map ":" 'org-agenda-set-tags)
+(org-defkey org-agenda-mode-map "." 'org-agenda-goto-today)
+(org-defkey org-agenda-mode-map "j" 'org-agenda-goto-date)
+(org-defkey org-agenda-mode-map "d" 'org-agenda-day-view)
+(org-defkey org-agenda-mode-map "w" 'org-agenda-week-view)
+(org-defkey org-agenda-mode-map "m" 'org-agenda-month-view)
+(org-defkey org-agenda-mode-map "y" 'org-agenda-year-view)
+(org-defkey org-agenda-mode-map [(shift right)] 'org-agenda-date-later)
+(org-defkey org-agenda-mode-map [(shift left)] 'org-agenda-date-earlier)
+(org-defkey org-agenda-mode-map [?\C-c ?\C-x (right)] 'org-agenda-date-later)
+(org-defkey org-agenda-mode-map [?\C-c ?\C-x (left)] 'org-agenda-date-earlier)
+
+(org-defkey org-agenda-mode-map ">" 'org-agenda-date-prompt)
+(org-defkey org-agenda-mode-map "\C-c\C-s" 'org-agenda-schedule)
+(org-defkey org-agenda-mode-map "\C-c\C-d" 'org-agenda-deadline)
(let ((l '(1 2 3 4 5 6 7 8 9 0)))
- (while l (define-key org-agenda-mode-map
+ (while l (org-defkey org-agenda-mode-map
(int-to-string (pop l)) 'digit-argument)))
-(define-key org-agenda-mode-map "f" 'org-agenda-follow-mode)
-(define-key org-agenda-mode-map "l" 'org-agenda-log-mode)
-(define-key org-agenda-mode-map "D" 'org-agenda-toggle-diary)
-(define-key org-agenda-mode-map "g" 'org-agenda-toggle-time-grid)
-(define-key org-agenda-mode-map "r" 'org-agenda-redo)
-(define-key org-agenda-mode-map "q" 'org-agenda-quit)
-(define-key org-agenda-mode-map "x" 'org-agenda-exit)
-(define-key org-agenda-mode-map "s" 'org-save-all-org-buffers)
-(define-key org-agenda-mode-map "P" 'org-agenda-show-priority)
-(define-key org-agenda-mode-map "T" 'org-agenda-show-tags)
-(define-key org-agenda-mode-map "n" 'next-line)
-(define-key org-agenda-mode-map "p" 'previous-line)
-(define-key org-agenda-mode-map "\C-n" 'org-agenda-next-date-line)
-(define-key org-agenda-mode-map "\C-p" 'org-agenda-previous-date-line)
-(define-key org-agenda-mode-map "," 'org-agenda-priority)
-(define-key org-agenda-mode-map "\C-c," 'org-agenda-priority)
-(define-key org-agenda-mode-map "i" 'org-agenda-diary-entry)
-(define-key org-agenda-mode-map "c" 'org-agenda-goto-calendar)
+(org-defkey org-agenda-mode-map "f" 'org-agenda-follow-mode)
+(org-defkey org-agenda-mode-map "l" 'org-agenda-log-mode)
+(org-defkey org-agenda-mode-map "D" 'org-agenda-toggle-diary)
+(org-defkey org-agenda-mode-map "G" 'org-agenda-toggle-time-grid)
+(org-defkey org-agenda-mode-map "r" 'org-agenda-redo)
+(org-defkey org-agenda-mode-map "g" 'org-agenda-redo)
+(org-defkey org-agenda-mode-map "e" 'org-agenda-execute)
+(org-defkey org-agenda-mode-map "q" 'org-agenda-quit)
+(org-defkey org-agenda-mode-map "x" 'org-agenda-exit)
+(org-defkey org-agenda-mode-map "\C-x\C-w" 'org-write-agenda)
+(org-defkey org-agenda-mode-map "s" 'org-save-all-org-buffers)
+(org-defkey org-agenda-mode-map "\C-x\C-s" 'org-save-all-org-buffers)
+(org-defkey org-agenda-mode-map "P" 'org-agenda-show-priority)
+(org-defkey org-agenda-mode-map "T" 'org-agenda-show-tags)
+(org-defkey org-agenda-mode-map "n" 'next-line)
+(org-defkey org-agenda-mode-map "p" 'previous-line)
+(org-defkey org-agenda-mode-map "\C-c\C-n" 'org-agenda-next-date-line)
+(org-defkey org-agenda-mode-map "\C-c\C-p" 'org-agenda-previous-date-line)
+(org-defkey org-agenda-mode-map "," 'org-agenda-priority)
+(org-defkey org-agenda-mode-map "\C-c," 'org-agenda-priority)
+(org-defkey org-agenda-mode-map "i" 'org-agenda-diary-entry)
+(org-defkey org-agenda-mode-map "c" 'org-agenda-goto-calendar)
(eval-after-load "calendar"
- '(define-key calendar-mode-map org-calendar-to-agenda-key
+ '(org-defkey calendar-mode-map org-calendar-to-agenda-key
'org-calendar-goto-agenda))
-(define-key org-agenda-mode-map "C" 'org-agenda-convert-date)
-(define-key org-agenda-mode-map "m" 'org-agenda-phases-of-moon)
-(define-key org-agenda-mode-map "M" 'org-agenda-phases-of-moon)
-(define-key org-agenda-mode-map "S" 'org-agenda-sunrise-sunset)
-(define-key org-agenda-mode-map "h" 'org-agenda-holidays)
-(define-key org-agenda-mode-map "H" 'org-agenda-holidays)
-(define-key org-agenda-mode-map "+" 'org-agenda-priority-up)
-(define-key org-agenda-mode-map "I" 'org-agenda-clock-in)
-(define-key org-agenda-mode-map "O" 'org-agenda-clock-out)
-(define-key org-agenda-mode-map "X" 'org-agenda-clock-cancel)
-(define-key org-agenda-mode-map "-" 'org-agenda-priority-down)
-(define-key org-agenda-mode-map (org-key 'S-up) 'org-agenda-priority-up)
-(define-key org-agenda-mode-map (org-key 'S-down) 'org-agenda-priority-down)
-(define-key org-agenda-mode-map [?\C-c ?\C-x (up)] 'org-agenda-priority-up)
-(define-key org-agenda-mode-map [?\C-c ?\C-x (down)] 'org-agenda-priority-down)
-(define-key org-agenda-mode-map [(right)] 'org-agenda-later)
-(define-key org-agenda-mode-map [(left)] 'org-agenda-earlier)
-(define-key org-agenda-mode-map "\C-c\C-x\C-c" 'org-export-icalendar-combine-agenda-files)
+(org-defkey org-agenda-mode-map "C" 'org-agenda-convert-date)
+(org-defkey org-agenda-mode-map "M" 'org-agenda-phases-of-moon)
+(org-defkey org-agenda-mode-map "S" 'org-agenda-sunrise-sunset)
+(org-defkey org-agenda-mode-map "h" 'org-agenda-holidays)
+(org-defkey org-agenda-mode-map "H" 'org-agenda-holidays)
+(org-defkey org-agenda-mode-map "\C-c\C-x\C-i" 'org-agenda-clock-in)
+(org-defkey org-agenda-mode-map "I" 'org-agenda-clock-in)
+(org-defkey org-agenda-mode-map "\C-c\C-x\C-o" 'org-agenda-clock-out)
+(org-defkey org-agenda-mode-map "O" 'org-agenda-clock-out)
+(org-defkey org-agenda-mode-map "\C-c\C-x\C-x" 'org-agenda-clock-cancel)
+(org-defkey org-agenda-mode-map "X" 'org-agenda-clock-cancel)
+(org-defkey org-agenda-mode-map "\C-c\C-x\C-j" 'org-clock-goto)
+(org-defkey org-agenda-mode-map "J" 'org-clock-goto)
+(org-defkey org-agenda-mode-map "+" 'org-agenda-priority-up)
+(org-defkey org-agenda-mode-map "-" 'org-agenda-priority-down)
+(org-defkey org-agenda-mode-map [(shift up)] 'org-agenda-priority-up)
+(org-defkey org-agenda-mode-map [(shift down)] 'org-agenda-priority-down)
+(org-defkey org-agenda-mode-map [?\C-c ?\C-x (up)] 'org-agenda-priority-up)
+(org-defkey org-agenda-mode-map [?\C-c ?\C-x (down)] 'org-agenda-priority-down)
+(org-defkey org-agenda-mode-map [(right)] 'org-agenda-later)
+(org-defkey org-agenda-mode-map [(left)] 'org-agenda-earlier)
+(org-defkey org-agenda-mode-map "\C-c\C-x\C-c" 'org-agenda-columns)
+
+(org-defkey org-agenda-mode-map "[" 'org-agenda-manipulate-query-add)
+(org-defkey org-agenda-mode-map "]" 'org-agenda-manipulate-query-subtract)
+(org-defkey org-agenda-mode-map "{" 'org-agenda-manipulate-query-add-re)
+(org-defkey org-agenda-mode-map "}" 'org-agenda-manipulate-query-subtract-re)
+
(defvar org-agenda-keymap (copy-keymap org-agenda-mode-map)
"Local keymap for agenda entries from Org-mode.")
-(define-key org-agenda-keymap
+(org-defkey org-agenda-keymap
(if (featurep 'xemacs) [(button2)] [(mouse-2)]) 'org-agenda-goto-mouse)
-(define-key org-agenda-keymap
+(org-defkey org-agenda-keymap
(if (featurep 'xemacs) [(button3)] [(mouse-3)]) 'org-agenda-show-mouse)
(when org-agenda-mouse-1-follows-link
- (define-key org-agenda-keymap [follow-link] 'mouse-face))
+ (org-defkey org-agenda-keymap [follow-link] 'mouse-face))
(easy-menu-define org-agenda-menu org-agenda-mode-map "Agenda menu"
'("Agenda"
("Agenda Files")
["Goto Today" org-agenda-goto-today (org-agenda-check-type nil 'agenda 'timeline)]
["Next Dates" org-agenda-later (org-agenda-check-type nil 'agenda)]
["Previous Dates" org-agenda-earlier (org-agenda-check-type nil 'agenda)]
+ ["Jump to date" org-agenda-goto-date (org-agenda-check-type nil 'agenda)]
"--"
- ("Tags"
+ ("Tags and Properties"
["Show all Tags" org-agenda-show-tags t]
- ["Set Tags" org-agenda-set-tags t])
+ ["Set Tags current line" org-agenda-set-tags (not (org-region-active-p))]
+ ["Change tag in region" org-agenda-set-tags (org-region-active-p)]
+ "--"
+ ["Column View" org-columns t])
("Date/Schedule"
["Schedule" org-agenda-schedule t]
["Set Deadline" org-agenda-deadline t]
"--"
- ["Change date +1 day" org-agenda-date-later (org-agenda-check-type nil 'agenda 'timeline)]
- ["Change date -1 day" org-agenda-date-earlier (org-agenda-check-type nil 'agenda 'timeline)]
- ["Change date to ..." org-agenda-date-prompt (org-agenda-check-type nil 'agenda 'timeline)])
+ ["Change Date +1 day" org-agenda-date-later (org-agenda-check-type nil 'agenda 'timeline)]
+ ["Change Date -1 day" org-agenda-date-earlier (org-agenda-check-type nil 'agenda 'timeline)]
+ ["Change Date to ..." org-agenda-date-prompt (org-agenda-check-type nil 'agenda 'timeline)])
+ ("Clock"
+ ["Clock in" org-agenda-clock-in t]
+ ["Clock out" org-agenda-clock-out t]
+ ["Clock cancel" org-agenda-clock-cancel t]
+ ["Goto running clock" org-clock-goto t])
("Priority"
["Set Priority" org-agenda-priority t]
["Increase Priority" org-agenda-priority-up t]
:style radio :selected (equal org-agenda-ndays 1)]
["Week View" org-agenda-week-view :active (org-agenda-check-type nil 'agenda)
:style radio :selected (equal org-agenda-ndays 7)]
+ ["Month View" org-agenda-month-view :active (org-agenda-check-type nil 'agenda)
+ :style radio :selected (member org-agenda-ndays '(28 29 30 31))]
+ ["Year View" org-agenda-year-view :active (org-agenda-check-type nil 'agenda)
+ :style radio :selected (member org-agenda-ndays '(365 366))]
"--"
["Show Logbook entries" org-agenda-log-mode
:style toggle :selected org-agenda-show-log :active (org-agenda-check-type nil 'agenda 'timeline)]
:style toggle :selected org-agenda-include-diary :active (org-agenda-check-type nil 'agenda)]
["Use Time Grid" org-agenda-toggle-time-grid
:style toggle :selected org-agenda-use-time-grid :active (org-agenda-check-type nil 'agenda)])
+ ["Write view to file" org-write-agenda t]
["Rebuild buffer" org-agenda-redo t]
["Save all Org-mode Buffers" org-save-all-org-buffers t]
"--"
"In a series of undo commands, this is the list of remaning undo items.")
(defmacro org-if-unprotected (&rest body)
- "Execute BODY if ther is no `org-protected' text property at point."
+ "Execute BODY if there is no `org-protected' text property at point."
(declare (debug t))
`(unless (get-text-property (point) 'org-protected)
,@body))
(if (pop entry)
(with-current-buffer buf
(let ((last-undo-buffer buf)
- buffer-read-only)
+ (inhibit-read-only t))
(unless (memq buf org-agenda-undo-has-started-in)
(push buf org-agenda-undo-has-started-in)
(make-local-variable 'pending-undo-list)
(defvar org-agenda-restrict-begin (make-marker))
(defvar org-agenda-restrict-end (make-marker))
(defvar org-agenda-last-dispatch-buffer nil)
+(defvar org-agenda-overriding-restriction nil)
;;;###autoload
-(defun org-agenda (arg)
+(defun org-agenda (arg &optional keys restriction)
"Dispatch agenda commands to collect entries to the agenda buffer.
-Prompts for a character to select a command. Any prefix arg will be passed
+Prompts for a command to execute. Any prefix arg will be passed
on to the selected command. The default selections are:
-g
+
a Call `org-agenda-list' to display the agenda for current day or week.
t Call `org-todo-list' to display the global todo list.
T Call `org-todo-list' to display the global todo list, select only
m Call `org-tags-view' to display headlines with tags matching
a condition (the user is prompted for the condition).
M Like `m', but select only TODO entries, no ordinary headlines.
-l Create a timeeline for the current buffer.
+L Create a timeline for the current buffer.
+e Export views to associated files.
More commands can be added by configuring the variable
`org-agenda-custom-commands'. In particular, specific tags and TODO keyword
searches can be pre-defined in this way.
If the current buffer is in Org-mode and visiting a file, you can also
-first press `1' to indicate that the agenda should be temporarily (until the
-next use of \\[org-agenda]) restricted to the current file."
+first press `<' once to indicate that the agenda should be temporarily
+\(until the next use of \\[org-agenda]) restricted to the current file.
+Pressing `<' twice means to restrict to the current subtree or region
+\(if active)."
(interactive "P")
(catch 'exit
- (let* ((buf (current-buffer))
+ (let* ((prefix-descriptions nil)
+ (org-agenda-custom-commands-orig org-agenda-custom-commands)
+ (org-agenda-custom-commands
+ ;; normalize different versions
+ (delq nil
+ (mapcar
+ (lambda (x)
+ (cond ((stringp (cdr x))
+ (push x prefix-descriptions)
+ nil)
+ ((stringp (nth 1 x)) x)
+ ((not (nth 1 x)) (cons (car x) (cons "" (cddr x))))
+ (t (cons (car x) (cons "" (cdr x))))))
+ org-agenda-custom-commands)))
+ (buf (current-buffer))
(bfn (buffer-file-name (buffer-base-buffer)))
- (restrict-ok (and bfn (org-mode-p)))
- (custom org-agenda-custom-commands)
- c entry key type match lprops)
- ;; Turn off restriction
- (put 'org-agenda-files 'org-restrict nil)
- (setq org-agenda-restrict nil)
- (move-marker org-agenda-restrict-begin nil)
- (move-marker org-agenda-restrict-end nil)
+ entry key type match lprops ans)
+ ;; Turn off restriction unless there is an overriding one
+ (unless org-agenda-overriding-restriction
+ (put 'org-agenda-files 'org-restrict nil)
+ (setq org-agenda-restrict nil)
+ (move-marker org-agenda-restrict-begin nil)
+ (move-marker org-agenda-restrict-end nil))
+ ;; Delete old local properties
+ (put 'org-agenda-redo-command 'org-lprops nil)
;; Remember where this call originated
(setq org-agenda-last-dispatch-buffer (current-buffer))
- (save-window-excursion
- (delete-other-windows)
- (switch-to-buffer-other-window " *Agenda Commands*")
- (erase-buffer)
- (insert (eval-when-compile
- (let ((header
-"Press key for an agenda command:
--------------------------------- C Configure custom agenda commands
-a Agenda for current week or day
-t List of all TODO entries T Entries with special TODO kwd
-m Match a TAGS query M Like m, but only TODO entries
-L Timeline for current buffer # List stuck projects (!=configure)
-")
- (start 0))
- (while (string-match "\\(^\\| \\|(\\)\\(\\S-\\)\\( \\|=\\)" header start)
- (setq start (match-end 0))
- (add-text-properties (match-beginning 2) (match-end 2)
- '(face bold) header))
- header)))
- (while (setq entry (pop custom))
- (setq key (car entry) type (nth 1 entry) match (nth 2 entry))
- (insert (format "\n%-4s%-14s: %s"
- (org-add-props (copy-sequence key)
- '(face bold))
- (cond
- ((stringp type) type)
- ((eq type 'todo) "TODO keyword")
- ((eq type 'tags) "Tags query")
- ((eq type 'tags-todo) "Tags (TODO)")
- ((eq type 'tags-tree) "Tags tree")
- ((eq type 'todo-tree) "TODO kwd tree")
- ((eq type 'occur-tree) "Occur tree")
- ((functionp type) (symbol-name type))
- (t "???"))
- (if (stringp match)
- (org-add-props match nil 'face 'org-warning)
- (format "set of %d commands" (length match))))))
- (if restrict-ok
- (insert "\n"
- (org-add-props "1 Restrict call to current buffer 0 Restrict call to region or subtree" nil 'face 'org-table)))
- (goto-char (point-min))
- (if (fboundp 'fit-window-to-buffer) (fit-window-to-buffer))
- (message "Press key for agenda command%s"
- (if restrict-ok ", or [1] or [0] to restrict" ""))
- (setq c (read-char-exclusive))
- (message "")
- (when (memq c '(?L ?1 ?0))
- (if restrict-ok
- (put 'org-agenda-files 'org-restrict (list bfn))
- (error "Cannot restrict agenda to current buffer"))
- (with-current-buffer " *Agenda Commands*"
- (goto-char (point-max))
- (delete-region (point-at-bol) (point))
- (goto-char (point-min)))
- (when (eq c ?0)
+ (unless keys
+ (setq ans (org-agenda-get-restriction-and-command prefix-descriptions)
+ keys (car ans)
+ restriction (cdr ans)))
+ ;; Estabish the restriction, if any
+ (when (and (not org-agenda-overriding-restriction) restriction)
+ (put 'org-agenda-files 'org-restrict (list bfn))
+ (cond
+ ((eq restriction 'region)
+ (setq org-agenda-restrict t)
+ (move-marker org-agenda-restrict-begin (region-beginning))
+ (move-marker org-agenda-restrict-end (region-end)))
+ ((eq restriction 'subtree)
+ (save-excursion
(setq org-agenda-restrict t)
- (with-current-buffer buf
- (if (org-region-active-p)
- (progn
- (move-marker org-agenda-restrict-begin (region-beginning))
- (move-marker org-agenda-restrict-end (region-end)))
- (save-excursion
- (org-back-to-heading t)
- (move-marker org-agenda-restrict-begin (point))
- (move-marker org-agenda-restrict-end
- (progn (org-end-of-subtree t)))))))
- (unless (eq c ?L)
- (message "Press key for agenda command%s"
- (if restrict-ok " (restricted to current file)" ""))
- (setq c (read-char-exclusive)))
- (message "")))
+ (org-back-to-heading t)
+ (move-marker org-agenda-restrict-begin (point))
+ (move-marker org-agenda-restrict-end
+ (progn (org-end-of-subtree t)))))))
+
(require 'calendar) ; FIXME: can we avoid this for some commands?
;; For example the todo list should not need it (but does...)
(cond
- ((setq entry (assoc (char-to-string c) org-agenda-custom-commands))
- (if (symbolp (nth 1 entry))
+ ((setq entry (assoc keys org-agenda-custom-commands))
+ (if (or (symbolp (nth 2 entry)) (functionp (nth 2 entry)))
(progn
- (setq type (nth 1 entry) match (nth 2 entry) lprops (nth 3 entry)
- lprops (nth 3 entry))
+ (setq type (nth 2 entry) match (nth 3 entry) lprops (nth 4 entry))
+ (put 'org-agenda-redo-command 'org-lprops lprops)
(cond
+ ((eq type 'agenda)
+ (org-let lprops '(org-agenda-list current-prefix-arg)))
+ ((eq type 'alltodo)
+ (org-let lprops '(org-todo-list current-prefix-arg)))
+ ((eq type 'search)
+ (org-let lprops '(org-search-view current-prefix-arg match)))
+ ((eq type 'stuck)
+ (org-let lprops '(org-agenda-list-stuck-projects
+ current-prefix-arg)))
((eq type 'tags)
(org-let lprops '(org-tags-view current-prefix-arg match)))
((eq type 'tags-todo)
((eq type 'occur-tree)
(org-check-for-org-mode)
(org-let lprops '(org-occur match)))
+ ((functionp type)
+ (org-let lprops '(funcall type match)))
((fboundp type)
(org-let lprops '(funcall type match)))
(t (error "Invalid custom agenda command type %s" type))))
- (org-run-agenda-series (cddr entry))))
- ((equal c ?C) (customize-variable 'org-agenda-custom-commands))
- ((equal c ?a) (call-interactively 'org-agenda-list))
- ((equal c ?t) (call-interactively 'org-todo-list))
- ((equal c ?T) (org-call-with-arg 'org-todo-list (or arg '(4))))
- ((equal c ?m) (call-interactively 'org-tags-view))
- ((equal c ?M) (org-call-with-arg 'org-tags-view (or arg '(4))))
- ((equal c ?L)
- (unless restrict-ok
+ (org-run-agenda-series (nth 1 entry) (cddr entry))))
+ ((equal keys "C")
+ (setq org-agenda-custom-commands org-agenda-custom-commands-orig)
+ (customize-variable 'org-agenda-custom-commands))
+ ((equal keys "a") (call-interactively 'org-agenda-list))
+ ((equal keys "s") (call-interactively 'org-search-view))
+ ((equal keys "t") (call-interactively 'org-todo-list))
+ ((equal keys "T") (org-call-with-arg 'org-todo-list (or arg '(4))))
+ ((equal keys "m") (call-interactively 'org-tags-view))
+ ((equal keys "M") (org-call-with-arg 'org-tags-view (or arg '(4))))
+ ((equal keys "e") (call-interactively 'org-store-agenda-views))
+ ((equal keys "L")
+ (unless (org-mode-p)
(error "This is not an Org-mode file"))
- (org-call-with-arg 'org-timeline arg))
- ((equal c ?#) (call-interactively 'org-agenda-list-stuck-projects))
- ((equal c ?!) (customize-variable 'org-stuck-projects))
- (t (error "Invalid key"))))))
-
-(defun org-run-agenda-series (series)
- (org-prepare-agenda)
+ (unless restriction
+ (put 'org-agenda-files 'org-restrict (list bfn))
+ (org-call-with-arg 'org-timeline arg)))
+ ((equal keys "#") (call-interactively 'org-agenda-list-stuck-projects))
+ ((equal keys "/") (call-interactively 'org-occur-in-agenda-files))
+ ((equal keys "!") (customize-variable 'org-stuck-projects))
+ (t (error "Invalid agenda key"))))))
+
+(defun org-agenda-normalize-custom-commands (cmds)
+ (delq nil
+ (mapcar
+ (lambda (x)
+ (cond ((stringp (cdr x)) nil)
+ ((stringp (nth 1 x)) x)
+ ((not (nth 1 x)) (cons (car x) (cons "" (cddr x))))
+ (t (cons (car x) (cons "" (cdr x))))))
+ cmds)))
+
+(defun org-agenda-get-restriction-and-command (prefix-descriptions)
+ "The user interface for selecting an agenda command."
+ (catch 'exit
+ (let* ((bfn (buffer-file-name (buffer-base-buffer)))
+ (restrict-ok (and bfn (org-mode-p)))
+ (region-p (org-region-active-p))
+ (custom org-agenda-custom-commands)
+ (selstring "")
+ restriction second-time
+ c entry key type match prefixes rmheader header-end custom1 desc)
+ (save-window-excursion
+ (delete-other-windows)
+ (org-switch-to-buffer-other-window " *Agenda Commands*")
+ (erase-buffer)
+ (insert (eval-when-compile
+ (let ((header
+"
+Press key for an agenda command: < Buffer,subtree/region restriction
+-------------------------------- > Remove restriction
+a Agenda for current week or day e Export agenda views
+t List of all TODO entries T Entries with special TODO kwd
+m Match a TAGS query M Like m, but only TODO entries
+L Timeline for current buffer # List stuck projects (!=configure)
+s Search for keywords C Configure custom agenda commands
+/ Multi-occur
+")
+ (start 0))
+ (while (string-match
+ "\\(^\\| \\|(\\)\\(\\S-\\)\\( \\|=\\)"
+ header start)
+ (setq start (match-end 0))
+ (add-text-properties (match-beginning 2) (match-end 2)
+ '(face bold) header))
+ header)))
+ (setq header-end (move-marker (make-marker) (point)))
+ (while t
+ (setq custom1 custom)
+ (when (eq rmheader t)
+ (goto-line 1)
+ (re-search-forward ":" nil t)
+ (delete-region (match-end 0) (point-at-eol))
+ (forward-char 1)
+ (looking-at "-+")
+ (delete-region (match-end 0) (point-at-eol))
+ (move-marker header-end (match-end 0)))
+ (goto-char header-end)
+ (delete-region (point) (point-max))
+ (while (setq entry (pop custom1))
+ (setq key (car entry) desc (nth 1 entry)
+ type (nth 2 entry) match (nth 3 entry))
+ (if (> (length key) 1)
+ (add-to-list 'prefixes (string-to-char key))
+ (insert
+ (format
+ "\n%-4s%-14s: %s"
+ (org-add-props (copy-sequence key)
+ '(face bold))
+ (cond
+ ((string-match "\\S-" desc) desc)
+ ((eq type 'agenda) "Agenda for current week or day")
+ ((eq type 'alltodo) "List of all TODO entries")
+ ((eq type 'search) "Word search")
+ ((eq type 'stuck) "List of stuck projects")
+ ((eq type 'todo) "TODO keyword")
+ ((eq type 'tags) "Tags query")
+ ((eq type 'tags-todo) "Tags (TODO)")
+ ((eq type 'tags-tree) "Tags tree")
+ ((eq type 'todo-tree) "TODO kwd tree")
+ ((eq type 'occur-tree) "Occur tree")
+ ((functionp type) (if (symbolp type)
+ (symbol-name type)
+ "Lambda expression"))
+ (t "???"))
+ (cond
+ ((stringp match)
+ (org-add-props match nil 'face 'org-warning))
+ (match
+ (format "set of %d commands" (length match)))
+ (t ""))))))
+ (when prefixes
+ (mapc (lambda (x)
+ (insert
+ (format "\n%s %s"
+ (org-add-props (char-to-string x)
+ nil 'face 'bold)
+ (or (cdr (assoc (concat selstring (char-to-string x))
+ prefix-descriptions))
+ "Prefix key"))))
+ prefixes))
+ (goto-char (point-min))
+ (when (fboundp 'fit-window-to-buffer)
+ (if second-time
+ (if (not (pos-visible-in-window-p (point-max)))
+ (fit-window-to-buffer))
+ (setq second-time t)
+ (fit-window-to-buffer)))
+ (message "Press key for agenda command%s:"
+ (if (or restrict-ok org-agenda-overriding-restriction)
+ (if org-agenda-overriding-restriction
+ " (restriction lock active)"
+ (if restriction
+ (format " (restricted to %s)" restriction)
+ " (unrestricted)"))
+ ""))
+ (setq c (read-char-exclusive))
+ (message "")
+ (cond
+ ((assoc (char-to-string c) custom)
+ (setq selstring (concat selstring (char-to-string c)))
+ (throw 'exit (cons selstring restriction)))
+ ((memq c prefixes)
+ (setq selstring (concat selstring (char-to-string c))
+ prefixes nil
+ rmheader (or rmheader t)
+ custom (delq nil (mapcar
+ (lambda (x)
+ (if (or (= (length (car x)) 1)
+ (/= (string-to-char (car x)) c))
+ nil
+ (cons (substring (car x) 1) (cdr x))))
+ custom))))
+ ((and (not restrict-ok) (memq c '(?1 ?0 ?<)))
+ (message "Restriction is only possible in Org-mode buffers")
+ (ding) (sit-for 1))
+ ((eq c ?1)
+ (org-agenda-remove-restriction-lock 'noupdate)
+ (setq restriction 'buffer))
+ ((eq c ?0)
+ (org-agenda-remove-restriction-lock 'noupdate)
+ (setq restriction (if region-p 'region 'subtree)))
+ ((eq c ?<)
+ (org-agenda-remove-restriction-lock 'noupdate)
+ (setq restriction
+ (cond
+ ((eq restriction 'buffer)
+ (if region-p 'region 'subtree))
+ ((memq restriction '(subtree region))
+ nil)
+ (t 'buffer))))
+ ((eq c ?>)
+ (org-agenda-remove-restriction-lock 'noupdate)
+ (setq restriction nil))
+ ((and (equal selstring "") (memq c '(?s ?a ?t ?m ?L ?C ?e ?T ?M ?# ?! ?/)))
+ (throw 'exit (cons (setq selstring (char-to-string c)) restriction)))
+ ((and (> (length selstring) 0) (eq c ?\d))
+ (delete-window)
+ (org-agenda-get-restriction-and-command prefix-descriptions))
+
+ ((equal c ?q) (error "Abort"))
+ (t (error "Invalid key %c" c))))))))
+
+(defun org-run-agenda-series (name series)
+ (org-prepare-agenda name)
(let* ((org-agenda-multi t)
- (redo (list 'org-run-agenda-series (list 'quote series)))
+ (redo (list 'org-run-agenda-series name (list 'quote series)))
(cmds (car series))
(gprops (nth 1 series))
match ;; The byte compiler incorrectly complains about this. Keep it!
(setq type (car cmd) match (nth 1 cmd) lprops (nth 2 cmd))
(cond
((eq type 'agenda)
- (call-interactively 'org-agenda-list))
+ (org-let2 gprops lprops
+ '(call-interactively 'org-agenda-list)))
((eq type 'alltodo)
- (call-interactively 'org-todo-list))
+ (org-let2 gprops lprops
+ '(call-interactively 'org-todo-list)))
+ ((eq type 'search)
+ (org-let2 gprops lprops
+ '(org-search-view current-prefix-arg match)))
((eq type 'stuck)
- (call-interactively 'org-agenda-list-stuck-projects))
+ (org-let2 gprops lprops
+ '(call-interactively 'org-agenda-list-stuck-projects)))
((eq type 'tags)
(org-let2 gprops lprops
'(org-tags-view current-prefix-arg match)))
;;;###autoload
(defmacro org-batch-agenda (cmd-key &rest parameters)
- "Run an agenda command in batch mode, send result to STDOUT.
-CMD-KEY is a string that is also a key in `org-agenda-custom-commands'.
+ "Run an agenda command in batch mode and send the result to STDOUT.
+If CMD-KEY is a string of length 1, it is used as a key in
+`org-agenda-custom-commands' and triggers this command. If it is a
+longer string it is used as a tags/todo match string.
Paramters are alternating variable names and values that will be bound
before running the agenda command."
(let (pars)
(while parameters
(push (list (pop parameters) (if parameters (pop parameters))) pars))
- (flet ((read-char-exclusive () (string-to-char cmd-key)))
- (eval (list 'let (nreverse pars) '(org-agenda nil))))
- (set-buffer "*Org Agenda*")
- (princ (buffer-string))))
+ (if (> (length cmd-key) 2)
+ (eval (list 'let (nreverse pars)
+ (list 'org-tags-view nil cmd-key)))
+ (eval (list 'let (nreverse pars) (list 'org-agenda nil cmd-key))))
+ (set-buffer org-agenda-buffer-name)
+ (princ (org-encode-for-stdout (buffer-string)))))
+
+(defun org-encode-for-stdout (string)
+ (if (fboundp 'encode-coding-string)
+ (encode-coding-string string buffer-file-coding-system)
+ string))
+
+(defvar org-agenda-info nil)
+
+;;;###autoload
+(defmacro org-batch-agenda-csv (cmd-key &rest parameters)
+ "Run an agenda command in batch mode and send the result to STDOUT.
+If CMD-KEY is a string of length 1, it is used as a key in
+`org-agenda-custom-commands' and triggers this command. If it is a
+longer string it is used as a tags/todo match string.
+Paramters are alternating variable names and values that will be bound
+before running the agenda command.
+
+The output gives a line for each selected agenda item. Each
+item is a list of comma-separated values, like this:
+
+category,head,type,todo,tags,date,time,extra,priority-l,priority-n
+
+category The category of the item
+head The headline, without TODO kwd, TAGS and PRIORITY
+type The type of the agenda entry, can be
+ todo selected in TODO match
+ tagsmatch selected in tags match
+ diary imported from diary
+ deadline a deadline on given date
+ scheduled scheduled on given date
+ timestamp entry has timestamp on given date
+ closed entry was closed on given date
+ upcoming-deadline warning about deadline
+ past-scheduled forwarded scheduled item
+ block entry has date block including g. date
+todo The todo keyword, if any
+tags All tags including inherited ones, separated by colons
+date The relevant date, like 2007-2-14
+time The time, like 15:00-16:50
+extra Sting with extra planning info
+priority-l The priority letter if any was given
+priority-n The computed numerical priority
+agenda-day The day in the agenda where this is listed"
+
+ (let (pars)
+ (while parameters
+ (push (list (pop parameters) (if parameters (pop parameters))) pars))
+ (push (list 'org-agenda-remove-tags t) pars)
+ (if (> (length cmd-key) 2)
+ (eval (list 'let (nreverse pars)
+ (list 'org-tags-view nil cmd-key)))
+ (eval (list 'let (nreverse pars) (list 'org-agenda nil cmd-key))))
+ (set-buffer org-agenda-buffer-name)
+ (let* ((lines (org-split-string (buffer-string) "\n"))
+ line)
+ (while (setq line (pop lines))
+ (catch 'next
+ (if (not (get-text-property 0 'org-category line)) (throw 'next nil))
+ (setq org-agenda-info
+ (org-fix-agenda-info (text-properties-at 0 line)))
+ (princ
+ (org-encode-for-stdout
+ (mapconcat 'org-agenda-export-csv-mapper
+ '(org-category txt type todo tags date time-of-day extra
+ priority-letter priority agenda-day)
+ ",")))
+ (princ "\n"))))))
+
+(defun org-fix-agenda-info (props)
+ "Make sure all properties on an agenda item have a canonical form,
+so the export commands can easily use it."
+ (let (tmp re)
+ (when (setq tmp (plist-get props 'tags))
+ (setq props (plist-put props 'tags (mapconcat 'identity tmp ":"))))
+ (when (setq tmp (plist-get props 'date))
+ (if (integerp tmp) (setq tmp (calendar-gregorian-from-absolute tmp)))
+ (let ((calendar-date-display-form '(year "-" month "-" day)))
+ '((format "%4d, %9s %2s, %4s" dayname monthname day year))
+
+ (setq tmp (calendar-date-string tmp)))
+ (setq props (plist-put props 'date tmp)))
+ (when (setq tmp (plist-get props 'day))
+ (if (integerp tmp) (setq tmp (calendar-gregorian-from-absolute tmp)))
+ (let ((calendar-date-display-form '(year "-" month "-" day)))
+ (setq tmp (calendar-date-string tmp)))
+ (setq props (plist-put props 'day tmp))
+ (setq props (plist-put props 'agenda-day tmp)))
+ (when (setq tmp (plist-get props 'txt))
+ (when (string-match "\\[#\\([A-Z0-9]\\)\\] ?" tmp)
+ (plist-put props 'priority-letter (match-string 1 tmp))
+ (setq tmp (replace-match "" t t tmp)))
+ (when (and (setq re (plist-get props 'org-todo-regexp))
+ (setq re (concat "\\`\\.*" re " ?"))
+ (string-match re tmp))
+ (plist-put props 'todo (match-string 1 tmp))
+ (setq tmp (replace-match "" t t tmp)))
+ (plist-put props 'txt tmp)))
+ props)
+
+(defun org-agenda-export-csv-mapper (prop)
+ (let ((res (plist-get org-agenda-info prop)))
+ (setq res
+ (cond
+ ((not res) "")
+ ((stringp res) res)
+ (t (prin1-to-string res))))
+ (while (string-match "," res)
+ (setq res (replace-match ";" t t res)))
+ (org-trim res)))
+
+
+;;;###autoload
+(defun org-store-agenda-views (&rest parameters)
+ (interactive)
+ (eval (list 'org-batch-store-agenda-views)))
+
+;; FIXME, why is this a macro?????
+;;;###autoload
+(defmacro org-batch-store-agenda-views (&rest parameters)
+ "Run all custom agenda commands that have a file argument."
+ (let ((cmds (org-agenda-normalize-custom-commands org-agenda-custom-commands))
+ (pop-up-frames nil)
+ (dir default-directory)
+ pars cmd thiscmdkey files opts)
+ (while parameters
+ (push (list (pop parameters) (if parameters (pop parameters))) pars))
+ (setq pars (reverse pars))
+ (save-window-excursion
+ (while cmds
+ (setq cmd (pop cmds)
+ thiscmdkey (car cmd)
+ opts (nth 4 cmd)
+ files (nth 5 cmd))
+ (if (stringp files) (setq files (list files)))
+ (when files
+ (eval (list 'let (append org-agenda-exporter-settings opts pars)
+ (list 'org-agenda nil thiscmdkey)))
+ (set-buffer org-agenda-buffer-name)
+ (while files
+ (eval (list 'let (append org-agenda-exporter-settings opts pars)
+ (list 'org-write-agenda
+ (expand-file-name (pop files) dir) t))))
+ (and (get-buffer org-agenda-buffer-name)
+ (kill-buffer org-agenda-buffer-name)))))))
+
+(defun org-write-agenda (file &optional nosettings)
+ "Write the current buffer (an agenda view) as a file.
+Depending on the extension of the file name, plain text (.txt),
+HTML (.html or .htm) or Postscript (.ps) is produced.
+If the extension is .ics, run icalendar export over all files used
+to construct the agenda and limit the export to entries listed in the
+agenda now.
+If NOSETTINGS is given, do not scope the settings of
+`org-agenda-exporter-settings' into the export commands. This is used when
+the settings have already been scoped and we do not wish to overrule other,
+higher priority settings."
+ (interactive "FWrite agenda to file: ")
+ (if (not (file-writable-p file))
+ (error "Cannot write agenda to file %s" file))
+ (cond
+ ((string-match "\\.html?\\'" file) (require 'htmlize))
+ ((string-match "\\.ps\\'" file) (require 'ps-print)))
+ (org-let (if nosettings nil org-agenda-exporter-settings)
+ '(save-excursion
+ (save-window-excursion
+ (cond
+ ((string-match "\\.html?\\'" file)
+ (set-buffer (htmlize-buffer (current-buffer)))
+
+ (when (and org-agenda-export-html-style
+ (string-match "<style>" org-agenda-export-html-style))
+ ;; replace <style> section with org-agenda-export-html-style
+ (goto-char (point-min))
+ (kill-region (- (search-forward "<style") 6)
+ (search-forward "</style>"))
+ (insert org-agenda-export-html-style))
+ (write-file file)
+ (kill-buffer (current-buffer))
+ (message "HTML written to %s" file))
+ ((string-match "\\.ps\\'" file)
+ (ps-print-buffer-with-faces file)
+ (message "Postscript written to %s" file))
+ ((string-match "\\.ics\\'" file)
+ (let ((org-agenda-marker-table
+ (org-create-marker-find-array
+ (org-agenda-collect-markers)))
+ (org-icalendar-verify-function 'org-check-agenda-marker-table)
+ (org-combined-agenda-icalendar-file file))
+ (apply 'org-export-icalendar 'combine (org-agenda-files))))
+ (t
+ (let ((bs (buffer-string)))
+ (find-file file)
+ (insert bs)
+ (save-buffer 0)
+ (kill-buffer (current-buffer))
+ (message "Plain text written to %s" file))))))
+ (set-buffer org-agenda-buffer-name)))
+
+(defun org-agenda-collect-markers ()
+ "Collect the markers pointing to entries in the agenda buffer."
+ (let (m markers)
+ (save-excursion
+ (goto-char (point-min))
+ (while (not (eobp))
+ (when (setq m (or (get-text-property (point) 'org-hd-marker)
+ (get-text-property (point) 'org-marker)))
+ (push m markers))
+ (beginning-of-line 2)))
+ (nreverse markers)))
+
+(defun org-create-marker-find-array (marker-list)
+ "Create a alist of files names with all marker positions in that file."
+ (let (f tbl m a p)
+ (while (setq m (pop marker-list))
+ (setq p (marker-position m)
+ f (buffer-file-name (or (buffer-base-buffer
+ (marker-buffer m))
+ (marker-buffer m))))
+ (if (setq a (assoc f tbl))
+ (push (marker-position m) (cdr a))
+ (push (list f p) tbl)))
+ (mapcar (lambda (x) (setcdr x (sort (copy-sequence (cdr x)) '<)) x)
+ tbl)))
+
+(defvar org-agenda-marker-table nil) ; dyamically scoped parameter
+(defun org-check-agenda-marker-table ()
+ "Check of the current entry is on the marker list."
+ (let ((file (buffer-file-name (or (buffer-base-buffer) (current-buffer))))
+ a)
+ (and (setq a (assoc file org-agenda-marker-table))
+ (save-match-data
+ (save-excursion
+ (org-back-to-heading t)
+ (member (point) (cdr a)))))))
(defmacro org-no-read-only (&rest body)
"Inhibit read-only for BODY."
"Fit the window to the buffer size."
(and (memq org-agenda-window-setup '(reorganize-frame))
(fboundp 'fit-window-to-buffer)
- (fit-window-to-buffer nil (/ (* (frame-height) 3) 4)
- (/ (frame-height) 2))))
+ (fit-window-to-buffer
+ nil
+ (floor (* (frame-height) (cdr org-agenda-window-frame-fractions)))
+ (floor (* (frame-height) (car org-agenda-window-frame-fractions))))))
;;; Agenda file list
"Get the list of agenda files.
Optional UNRESTRICTED means return the full list even if a restriction
is currently in place."
- (cond
- ((and (not unrestricted) (get 'org-agenda-files 'org-restrict)))
- ((stringp org-agenda-files) (org-read-agenda-file-list))
- ((listp org-agenda-files) org-agenda-files)
- (t (error "Invalid value of `org-agenda-files'"))))
+ (let ((files
+ (cond
+ ((and (not unrestricted) (get 'org-agenda-files 'org-restrict)))
+ ((stringp org-agenda-files) (org-read-agenda-file-list))
+ ((listp org-agenda-files) org-agenda-files)
+ (t (error "Invalid value of `org-agenda-files'")))))
+ (setq files (apply 'append
+ (mapcar (lambda (f)
+ (if (file-directory-p f)
+ (directory-files f t
+ org-agenda-file-regexp)
+ (list f)))
+ files)))
+ (if org-agenda-skip-unavailable-files
+ (delq nil
+ (mapcar (function
+ (lambda (file)
+ (and (file-readable-p file) file)))
+ files))
+ files))) ; `org-check-agenda-file' will remove them from the list
(defun org-edit-agenda-file-list ()
"Edit the list of agenda files.
(org-install-agenda-files-menu)
(message "New agenda file list installed"))
nil 'local)
- (message (substitute-command-keys
- "Edit list and finish with \\[save-buffer]")))
+ (message "%s" (substitute-command-keys
+ "Edit list and finish with \\[save-buffer]")))
(customize-variable 'org-agenda-files)))
(defun org-store-new-agenda-file-list (list)
(find-file (car fs)))
(if (buffer-base-buffer) (switch-to-buffer (buffer-base-buffer)))))
-(defun org-agenda-file-to-end ()
- "Move/add the current file to the end of the agenda file list.
-If the file is not present in the list, it is appended to the list. If it is
-present, it is moved there."
- (interactive)
- (org-agenda-file-to-front 'to-end))
-
(defun org-agenda-file-to-front (&optional to-end)
"Move/add the current file to the top of the agenda file list.
If the file is not present in the list, it is added to the front. If it is
present, it is moved there. With optional argument TO-END, add/move to the
end of the list."
(interactive "P")
- (let ((file-alist (mapcar (lambda (x)
+ (let ((org-agenda-skip-unavailable-files nil)
+ (file-alist (mapcar (lambda (x)
(cons (file-truename x) x))
(org-agenda-files t)))
(ctf (file-truename buffer-file-name))
These are the files which are being checked for agenda entries.
Optional argument FILE means, use this file instead of the current."
(interactive)
- (let* ((file (or file buffer-file-name))
+ (let* ((org-agenda-skip-unavailable-files nil)
+ (file (or file buffer-file-name))
(true-file (file-truename file))
(afile (abbreviate-file-name file))
(files (delq nil (mapcar
(org-store-new-agenda-file-list files)
(org-install-agenda-files-menu)
(message "Removed file: %s" afile))
- (message "File was not in list: %s" afile))))
+ (message "File was not in list: %s (not removed)" afile))))
(defun org-file-menu-entry (file)
(vector file (list 'find-file file) t))
(defvar org-agenda-multi nil) ; dynammically scoped
(defvar org-agenda-buffer-name "*Org Agenda*")
(defvar org-pre-agenda-window-conf nil)
-(defun org-prepare-agenda ()
+(defvar org-agenda-name nil)
+(defun org-prepare-agenda (&optional name)
+ (setq org-todo-keywords-for-agenda nil)
+ (setq org-done-keywords-for-agenda nil)
(if org-agenda-multi
(progn
(setq buffer-read-only nil)
(goto-char (point-max))
- (unless (= (point) 1)
+ (unless (or (bobp) org-agenda-compact-blocks)
(insert "\n" (make-string (window-width) ?=) "\n"))
(narrow-to-region (point) (point-max)))
- (org-agenda-maybe-reset-markers 'force)
+ (org-agenda-reset-markers)
(org-prepare-agenda-buffers (org-agenda-files))
+ (setq org-todo-keywords-for-agenda
+ (org-uniquify org-todo-keywords-for-agenda))
+ (setq org-done-keywords-for-agenda
+ (org-uniquify org-done-keywords-for-agenda))
(let* ((abuf (get-buffer-create org-agenda-buffer-name))
(awin (get-buffer-window abuf)))
(cond
((equal org-agenda-window-setup 'current-window)
(switch-to-buffer abuf))
((equal org-agenda-window-setup 'other-window)
- (switch-to-buffer-other-window abuf))
+ (org-switch-to-buffer-other-window abuf))
((equal org-agenda-window-setup 'other-frame)
(switch-to-buffer-other-frame abuf))
((equal org-agenda-window-setup 'reorganize-frame)
(delete-other-windows)
- (switch-to-buffer-other-window abuf))))
+ (org-switch-to-buffer-other-window abuf))))
(setq buffer-read-only nil)
(erase-buffer)
- (org-agenda-mode))
+ (org-agenda-mode)
+ (and name (not org-agenda-name)
+ (org-set-local 'org-agenda-name name)))
(setq buffer-read-only nil))
(defun org-finalize-agenda ()
"Finishing touch for the agenda buffer, called just before displaying it."
(unless org-agenda-multi
- (org-agenda-align-tags)
(save-excursion
- (let ((buffer-read-only))
+ (let ((inhibit-read-only t))
(goto-char (point-min))
(while (org-activate-bracket-links (point-max))
(add-text-properties (match-beginning 0) (match-end 0)
- '(face org-link))))
- (run-hooks 'org-finalize-agenda-hook))))
+ '(face org-link)))
+ (org-agenda-align-tags)
+ (unless org-agenda-with-colors
+ (remove-text-properties (point-min) (point-max) '(face nil))))
+ (if (and (boundp 'org-overriding-columns-format)
+ org-overriding-columns-format)
+ (org-set-local 'org-overriding-columns-format
+ org-overriding-columns-format))
+ (if (and (boundp 'org-agenda-view-columns-initially)
+ org-agenda-view-columns-initially)
+ (org-agenda-columns))
+ (when org-agenda-fontify-priorities
+ (org-fontify-priorities))
+ (run-hooks 'org-finalize-agenda-hook)
+ (setq org-agenda-type (get-text-property (point) 'org-agenda-type))
+ )))
+
+(defun org-fontify-priorities ()
+ "Make highest priority lines bold, and lowest italic."
+ (interactive)
+ (mapc (lambda (o) (if (eq (org-overlay-get o 'org-type) 'org-priority)
+ (org-delete-overlay o)))
+ (org-overlays-in (point-min) (point-max)))
+ (save-excursion
+ (let ((inhibit-read-only t)
+ b e p ov h l)
+ (goto-char (point-min))
+ (while (re-search-forward "\\[#\\(.\\)\\]" nil t)
+ (setq h (or (get-char-property (point) 'org-highest-priority)
+ org-highest-priority)
+ l (or (get-char-property (point) 'org-lowest-priority)
+ org-lowest-priority)
+ p (string-to-char (match-string 1))
+ b (match-beginning 0) e (point-at-eol)
+ ov (org-make-overlay b e))
+ (org-overlay-put
+ ov 'face
+ (cond ((listp org-agenda-fontify-priorities)
+ (cdr (assoc p org-agenda-fontify-priorities)))
+ ((equal p l) 'italic)
+ ((equal p h) 'bold)))
+ (org-overlay-put ov 'org-type 'org-priority)))))
(defun org-prepare-agenda-buffers (files)
"Create buffers for all agenda files, protect archived trees and comments."
(let ((pa '(:org-archived t))
(pc '(:org-comment t))
(pall '(:org-archived t :org-comment t))
+ (inhibit-read-only t)
(rea (concat ":" org-archive-tag ":"))
bmp file re)
(save-excursion
(save-restriction
(while (setq file (pop files))
- (org-check-agenda-file file)
- (set-buffer (org-get-agenda-file-buffer file))
+ (if (bufferp file)
+ (set-buffer file)
+ (org-check-agenda-file file)
+ (set-buffer (org-get-agenda-file-buffer file)))
(widen)
(setq bmp (buffer-modified-p))
+ (org-refresh-category-properties)
+ (setq org-todo-keywords-for-agenda
+ (append org-todo-keywords-for-agenda org-todo-keywords-1))
+ (setq org-done-keywords-for-agenda
+ (append org-done-keywords-for-agenda org-done-keywords))
(save-excursion
(remove-text-properties (point-min) (point-max) pall)
(when org-agenda-skip-archived-trees
(defvar org-agenda-skip-function nil
"Function to be called at each match during agenda construction.
-If this function return nil, the current match should not be skipped.
+If this function returns nil, the current match should not be skipped.
Otherwise, the function must return a position from where the search
should be continued.
+This may also be a Lisp form, it will be evaluated.
Never set this variable using `setq' or so, because then it will apply
to all future agenda commands. Instead, bind it with `let' to scope
-it dynamically into the agenda-constructing command.")
+it dynamically into the agenda-constructing command. A good way to set
+it is through options in org-agenda-custom-commands.")
(defun org-agenda-skip ()
"Throw to `:skip' in places that should be skipped.
Also moves point to the end of the skipped region, so that search can
continue from there."
- (let ((p (point-at-bol)) to)
+ (let ((p (point-at-bol)) to fp)
(and org-agenda-skip-archived-trees
(get-text-property p :org-archived)
(org-end-of-subtree t)
(org-end-of-subtree t)
(throw :skip t))
(if (equal (char-after p) ?#) (throw :skip t))
- (when (and (functionp org-agenda-skip-function)
+ (when (and (or (setq fp (functionp org-agenda-skip-function))
+ (consp org-agenda-skip-function))
(setq to (save-excursion
(save-match-data
- (funcall org-agenda-skip-function)))))
+ (if fp
+ (funcall org-agenda-skip-function)
+ (eval org-agenda-skip-function))))))
(goto-char to)
(throw :skip t))))
(push m org-agenda-markers)
m))
-(defun org-agenda-maybe-reset-markers (&optional force)
- "Reset markers created by `org-agenda'. But only if they are old enough."
- (if (or (and force (not org-agenda-multi))
- (> (- (time-to-seconds (current-time))
- org-agenda-last-marker-time)
- 5))
- (while org-agenda-markers
- (move-marker (pop org-agenda-markers) nil))))
-
-(defvar org-agenda-new-buffers nil
- "Buffers created to visit agenda files.")
+(defun org-agenda-reset-markers ()
+ "Reset markers created by `org-agenda'."
+ (while org-agenda-markers
+ (move-marker (pop org-agenda-markers) nil)))
(defun org-get-agenda-file-buffer (file)
"Get a buffer visiting FILE. If the buffer needs to be created, add
(with-current-buffer buf (save-buffer)))
(kill-buffer buf))))
-(defvar org-category-table nil)
-(defun org-get-category-table ()
- "Get the table of categories and positions in current buffer."
- (let (tbl)
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward "\\(^\\|\r\\)#\\+CATEGORY:[ \t]*\\(.*\\)" nil t)
- (push (cons (point) (org-trim (match-string 2))) tbl)))
- tbl))
-
(defun org-get-category (&optional pos)
"Get the category applying to position POS."
- (if (not org-category-table)
- (cond
- ((null org-category)
- (setq org-category
- (if buffer-file-name
- (file-name-sans-extension
- (file-name-nondirectory buffer-file-name))
- "???")))
- ((symbolp org-category) (symbol-name org-category))
- (t org-category))
- (let ((tbl org-category-table)
- (pos (or pos (point))))
- (while (and tbl (> (caar tbl) pos))
- (pop tbl))
- (or (cdar tbl) (cdr (nth (1- (length org-category-table))
- org-category-table))))))
+ (get-text-property (or pos (point)) 'org-category))
+
;;; Agenda timeline
+(defvar org-agenda-only-exact-dates nil) ; dynamically scoped
+
(defun org-timeline (&optional include-all)
"Show a time-sorted view of the entries in the current org file.
Only entries with a time stamp of today or later will be listed. With
(day-numbers (org-get-all-dates beg end 'no-ranges
t doclosed ; always include today
org-timeline-show-empty-dates))
+ (org-deadline-warning-days 0)
+ (org-agenda-only-exact-dates t)
(today (time-to-days (current-time)))
(past t)
args
s e rtn d emptyp)
(setq org-agenda-redo-command
(list 'progn
- (list 'switch-to-buffer-other-window (current-buffer))
+ (list 'org-switch-to-buffer-other-window (current-buffer))
(list 'org-timeline (list 'quote include-all))))
(if (not dopast)
;; Remove past dates from the list of dates.
(setq day-numbers (delq nil (mapcar (lambda(x)
(if (>= x today) x nil))
day-numbers))))
- (org-prepare-agenda)
+ (org-prepare-agenda (concat "Timeline "
+ (file-name-nondirectory buffer-file-name)))
(if doclosed (push :closed args))
(push :timestamp args)
+ (push :deadline args)
+ (push :scheduled args)
+ (push :sexp args)
(if dotodo (push :todo args))
(while (setq d (pop day-numbers))
(if (and (listp d) (eq (car d) :omitted))
(progn
(setq s (point))
(insert (format "\n[... %d empty days omitted]\n\n" (cdr d)))
- (put-text-property s (1- (point)) 'face 'org-level-3))
+ (put-text-property s (1- (point)) 'face 'org-agenda-structure))
(if (listp d) (setq d (car d) emptyp t) (setq emptyp nil))
(if (and (>= d today)
dopast
(setq date (calendar-gregorian-from-absolute d))
(setq s (point))
(setq rtn (and (not emptyp)
- (apply 'org-agenda-get-day-entries
- entry date args)))
+ (apply 'org-agenda-get-day-entries entry
+ date args)))
(if (or rtn (equal d today) org-timeline-show-empty-dates)
(progn
- (insert (calendar-day-name date) " "
- (number-to-string (extract-calendar-day date)) " "
- (calendar-month-name (extract-calendar-month date)) " "
- (number-to-string (extract-calendar-year date)) "\n")
-; FIXME: this gives a timezone problem
-; (insert (format-time-string org-agenda-date-format
-; (calendar-time-from-absolute d 0))
-; "\n")
- (put-text-property s (1- (point)) 'face 'org-level-3)
+ (insert
+ (if (stringp org-agenda-format-date)
+ (format-time-string org-agenda-format-date
+ (org-time-from-absolute date))
+ (funcall org-agenda-format-date date))
+ "\n")
+ (put-text-property s (1- (point)) 'face 'org-agenda-structure)
(put-text-property s (1- (point)) 'org-date-line t)
(if (equal d today)
(put-text-property s (1- (point)) 'org-today t))
(org-finalize-agenda)
(setq buffer-read-only t)))
-(defun org-get-all-dates (beg end &optional no-ranges force-today inactive empty)
+(defun org-get-all-dates (beg end &optional no-ranges force-today inactive empty pre-re)
"Return a list of all relevant day numbers from BEG to END buffer positions.
If NO-RANGES is non-nil, include only the start and end dates of a range,
not every single day in the range. If FORCE-TODAY is non-nil, make
sure that TODAY is included in the list. If INACTIVE is non-nil, also
inactive time stamps (those in square brackets) are included.
When EMPTY is non-nil, also include days without any entries."
- (let ((re (if inactive org-ts-regexp-both org-ts-regexp))
+ (let ((re (concat
+ (if pre-re pre-re "")
+ (if inactive org-ts-regexp-both org-ts-regexp)))
dates dates1 date day day1 day2 ts1 ts2)
(if force-today
(setq dates (list (time-to-days (current-time)))))
;;; Agenda Daily/Weekly
(defvar org-agenda-overriding-arguments nil) ; dynamically scoped parameter
+(defvar org-agenda-start-day nil) ; dynamically scoped parameter
(defvar org-agenda-last-arguments nil
"The arguments of the previous call to org-agenda")
(defvar org-starting-day nil) ; local variable in the agenda buffer
+(defvar org-agenda-span nil) ; local variable in the agenda buffer
(defvar org-include-all-loc nil) ; local variable
-
+(defvar org-agenda-remove-date nil) ; dynamically scoped FIXME: not used???
;;;###autoload
(defun org-agenda-list (&optional include-all start-day ndays)
- "Produce a weekly view from all files in variable `org-agenda-files'.
-The view will be for the current week, but from the overview buffer you
-will be able to go to other weeks.
-With one \\[universal-argument] prefix argument INCLUDE-ALL, all unfinished TODO items will
-also be shown, under the current date.
-With two \\[universal-argument] prefix argument INCLUDE-ALL, all TODO entries marked DONE
-on the days are also shown. See the variable `org-log-done' for how
-to turn on logging.
+ "Produce a daily/weekly view from all files in variable `org-agenda-files'.
+The view will be for the current day or week, but from the overview buffer
+you will be able to go to other days/weeks.
+
+With one \\[universal-argument] prefix argument INCLUDE-ALL,
+all unfinished TODO items will also be shown, before the agenda.
+This feature is considered obsolete, please use the TODO list or a block
+agenda instead.
+
+With a numeric prefix argument in an interactive call, the agenda will
+span INCLUDE-ALL days. Lisp programs should instead specify NDAYS to change
+the number of days. NDAYS defaults to `org-agenda-ndays'.
+
START-DAY defaults to TODAY, or to the most recent match for the weekday
-given in `org-agenda-start-on-weekday'.
-NDAYS defaults to `org-agenda-ndays'."
+given in `org-agenda-start-on-weekday'."
(interactive "P")
+ (if (and (integerp include-all) (> include-all 0))
+ (setq ndays include-all include-all nil))
+ (setq ndays (or ndays org-agenda-ndays)
+ start-day (or start-day org-agenda-start-day))
(if org-agenda-overriding-arguments
(setq include-all (car org-agenda-overriding-arguments)
start-day (nth 1 org-agenda-overriding-arguments)
ndays (nth 2 org-agenda-overriding-arguments)))
+ (if (stringp start-day)
+ ;; Convert to an absolute day number
+ (setq start-day (time-to-days (org-read-date nil t start-day))))
(setq org-agenda-last-arguments (list include-all start-day ndays))
(org-compile-prefix-format 'agenda)
(org-set-sorting-strategy 'agenda)
(require 'calendar)
(let* ((org-agenda-start-on-weekday
- (if (or (equal ndays 1)
- (and (null ndays) (equal 1 org-agenda-ndays)))
- nil org-agenda-start-on-weekday))
+ (if (or (equal ndays 7) (and (null ndays) (equal 7 org-agenda-ndays)))
+ org-agenda-start-on-weekday nil))
(thefiles (org-agenda-files))
(files thefiles)
- (today (time-to-days (current-time)))
+ (today (time-to-days
+ (time-subtract (current-time)
+ (list 0 (* 3600 org-extend-today-until) 0))))
(sd (or start-day today))
(start (if (or (null org-agenda-start-on-weekday)
(< org-agenda-ndays 7))
(d (- nt n1)))
(- sd (+ (if (< d 0) 7 0) d)))))
(day-numbers (list start))
+ (day-cnt 0)
(inhibit-redisplay (not debug-on-error))
s e rtn rtnall file date d start-pos end-pos todayp nd)
(setq org-agenda-redo-command
(push (1+ (car day-numbers)) day-numbers)
(setq ndays (1- ndays)))
(setq day-numbers (nreverse day-numbers))
- (org-prepare-agenda)
+ (org-prepare-agenda "Day/Week")
(org-set-local 'org-starting-day (car day-numbers))
(org-set-local 'org-include-all-loc include-all)
+ (org-set-local 'org-agenda-span
+ (org-agenda-ndays-to-span nd))
(when (and (or include-all org-agenda-include-all-todo)
(member today day-numbers))
(setq files thefiles
(when rtnall
(insert "ALL CURRENTLY OPEN TODO ITEMS:\n")
(add-text-properties (point-min) (1- (point))
- (list 'face 'org-level-3))
+ (list 'face 'org-agenda-structure))
(insert (org-finalize-agenda-entries rtnall) "\n")))
- (setq s (point))
- (insert (if (= nd 7) "Week-" "Day-") "agenda:\n")
- (add-text-properties s (1- (point)) (list 'face 'org-level-3))
+ (unless org-agenda-compact-blocks
+ (setq s (point))
+ (insert (capitalize (symbol-name (org-agenda-ndays-to-span nd)))
+ "-agenda:\n")
+ (add-text-properties s (1- (point)) (list 'face 'org-agenda-structure
+ 'org-date-line t)))
(while (setq d (pop day-numbers))
(setq date (calendar-gregorian-from-absolute d)
s (point))
(if org-agenda-show-log
(setq rtn (org-agenda-get-day-entries
file date
- :deadline :scheduled :timestamp :closed))
+ :deadline :scheduled :timestamp :sexp :closed))
(setq rtn (org-agenda-get-day-entries
file date
- :deadline :scheduled :timestamp)))
+ :deadline :scheduled :sexp :timestamp)))
(setq rtnall (append rtnall rtn))))
(if org-agenda-include-diary
(progn
(setq rtnall (append rtnall rtn))))
(if (or rtnall org-agenda-show-all-dates)
(progn
- (insert (format "%-9s %2d %s %4d\n"
- (calendar-day-name date)
- (extract-calendar-day date)
- (calendar-month-name (extract-calendar-month date))
- (extract-calendar-year date)))
-; FIXME: this gives a timezone problem
-; (insert (format-time-string org-agenda-date-format
-; (calendar-time-from-absolute d 0)) "\n")
- (put-text-property s (1- (point)) 'face 'org-level-3)
+ (setq day-cnt (1+ day-cnt))
+ (insert
+ (if (stringp org-agenda-format-date)
+ (format-time-string org-agenda-format-date
+ (org-time-from-absolute date))
+ (funcall org-agenda-format-date date))
+ "\n")
+ (put-text-property s (1- (point)) 'face 'org-agenda-structure)
(put-text-property s (1- (point)) 'org-date-line t)
+ (put-text-property s (1- (point)) 'org-day-cnt day-cnt)
(if todayp (put-text-property s (1- (point)) 'org-today t))
(if rtnall (insert
(org-finalize-agenda-entries
(org-agenda-add-time-grid-maybe
rtnall nd todayp))
"\n"))
- (put-text-property s (1- (point)) 'day d))))
+ (put-text-property s (1- (point)) 'day d)
+ (put-text-property s (1- (point)) 'org-day-cnt day-cnt))))
(goto-char (point-min))
(org-fit-agenda-window)
(unless (and (pos-visible-in-window-p (point-min))
(setq buffer-read-only t)
(message "")))
+(defun org-agenda-ndays-to-span (n)
+ (cond ((< n 7) 'day) ((= n 7) 'week) ((< n 32) 'month) (t 'year)))
+
+;;; Agenda word search
+
+(defvar org-agenda-search-history nil)
+
+;;;###autoload
+(defun org-search-view (&optional arg string)
+ "Show all entries that contain words or regular expressions.
+If the first character of the search string is an asterisks,
+search only the headlines.
+
+The search string is broken into \"words\" by splitting at whitespace.
+The individual words are then interpreted as a boolean expression with
+logical AND. Words prefixed with a minus must not occur in the entry.
+Words without a prefix or prefixed with a plus must occur in the entry.
+Matching is case-insensitive and the words are enclosed by word delimiters.
+
+Words enclosed by curly braces are interpreted as regular expressions
+that must or must not match in the entry.
+
+This command searches the agenda files, and in addition the files listed
+in `org-agenda-text-search-extra-files'."
+ (interactive "P")
+ (org-compile-prefix-format 'search)
+ (org-set-sorting-strategy 'search)
+ (org-prepare-agenda "SEARCH")
+ (let* ((props (list 'face nil
+ 'done-face 'org-done
+ 'org-not-done-regexp org-not-done-regexp
+ 'org-todo-regexp org-todo-regexp
+ 'mouse-face 'highlight
+ 'keymap org-agenda-keymap
+ 'help-echo (format "mouse-2 or RET jump to location")))
+ regexp rtn rtnall files file pos
+ marker priority category tags c neg re
+ ee txt beg end words regexps+ regexps- hdl-only buffer beg1 str)
+ (unless (and (not arg)
+ (stringp string)
+ (string-match "\\S-" string))
+ (setq string (read-string "[+-]Word/{Regexp} ...: "
+ (cond
+ ((integerp arg) (cons string arg))
+ (arg string))
+ 'org-agenda-search-history)))
+ (setq org-agenda-redo-command
+ (list 'org-search-view 'current-prefix-arg string))
+ (setq org-agenda-query-string string)
+
+ (if (equal (string-to-char string) ?*)
+ (setq hdl-only t
+ words (substring string 1))
+ (setq words string))
+ (setq words (org-split-string words))
+ (mapc (lambda (w)
+ (setq c (string-to-char w))
+ (if (equal c ?-)
+ (setq neg t w (substring w 1))
+ (if (equal c ?+)
+ (setq neg nil w (substring w 1))
+ (setq neg nil)))
+ (if (string-match "\\`{.*}\\'" w)
+ (setq re (substring w 1 -1))
+ (setq re (concat "\\<" (regexp-quote (downcase w)) "\\>")))
+ (if neg (push re regexps-) (push re regexps+)))
+ words)
+ (setq regexps+ (sort regexps+ (lambda (a b) (> (length a) (length b)))))
+ (if (not regexps+)
+ (setq regexp (concat "^" org-outline-regexp))
+ (setq regexp (pop regexps+))
+ (if hdl-only (setq regexp (concat "^" org-outline-regexp ".*?"
+ regexp))))
+ (setq files (append (org-agenda-files) org-agenda-text-search-extra-files)
+ rtnall nil)
+ (while (setq file (pop files))
+ (setq ee nil)
+ (catch 'nextfile
+ (org-check-agenda-file file)
+ (setq buffer (if (file-exists-p file)
+ (org-get-agenda-file-buffer file)
+ (error "No such file %s" file)))
+ (if (not buffer)
+ ;; If file does not exist, make sure an error message is sent
+ (setq rtn (list (format "ORG-AGENDA-ERROR: No such org-file %s"
+ file))))
+ (with-current-buffer buffer
+ (unless (org-mode-p)
+ (error "Agenda file %s is not in `org-mode'" file))
+ (let ((case-fold-search t))
+ (save-excursion
+ (save-restriction
+ (if org-agenda-restrict
+ (narrow-to-region org-agenda-restrict-begin
+ org-agenda-restrict-end)
+ (widen))
+ (goto-char (point-min))
+ (unless (or (org-on-heading-p)
+ (outline-next-heading))
+ (throw 'nextfile t))
+ (goto-char (max (point-min) (1- (point))))
+ (while (re-search-forward regexp nil t)
+ (org-back-to-heading t)
+ (skip-chars-forward "* ")
+ (setq beg (point-at-bol)
+ beg1 (point)
+ end (progn (outline-next-heading) (point)))
+ (catch :skip
+ (goto-char beg)
+ (org-agenda-skip)
+ (setq str (buffer-substring-no-properties
+ (point-at-bol)
+ (if hdl-only (point-at-eol) end)))
+ (mapc (lambda (wr) (when (string-match wr str)
+ (goto-char (1- end))
+ (throw :skip t)))
+ regexps-)
+ (mapc (lambda (wr) (unless (string-match wr str)
+ (goto-char (1- end))
+ (throw :skip t)))
+ regexps+)
+ (goto-char beg)
+ (setq marker (org-agenda-new-marker (point))
+ category (org-get-category)
+ tags (org-get-tags-at (point))
+ txt (org-format-agenda-item
+ ""
+ (buffer-substring-no-properties
+ beg1 (point-at-eol))
+ category tags))
+ (org-add-props txt props
+ 'org-marker marker 'org-hd-marker marker
+ 'priority 1000 'org-category category
+ 'type "search")
+ (push txt ee)
+ (goto-char (1- end)))))))))
+ (setq rtn (nreverse ee))
+ (setq rtnall (append rtnall rtn)))
+ (if org-agenda-overriding-header
+ (insert (org-add-props (copy-sequence org-agenda-overriding-header)
+ nil 'face 'org-agenda-structure) "\n")
+ (insert "Search words: ")
+ (add-text-properties (point-min) (1- (point))
+ (list 'face 'org-agenda-structure))
+ (setq pos (point))
+ (insert string "\n")
+ (add-text-properties pos (1- (point)) (list 'face 'org-warning))
+ (setq pos (point))
+ (unless org-agenda-multi
+ (insert "Press `[', `]' to add/sub word, `{', `}' to add/sub regexp, `C-u r' to edit\n")
+ (add-text-properties pos (1- (point))
+ (list 'face 'org-agenda-structure))))
+ (when rtnall
+ (insert (org-finalize-agenda-entries rtnall) "\n"))
+ (goto-char (point-min))
+ (org-fit-agenda-window)
+ (add-text-properties (point-min) (point-max) '(org-agenda-type search))
+ (org-finalize-agenda)
+ (setq buffer-read-only t)))
+
;;; Agenda TODO list
(defvar org-select-this-todo-keyword nil)
The prefix arg can be used to select a specific TODO keyword and limit
the list to these. When using \\[universal-argument], you will be prompted
for a keyword. A numeric prefix directly selects the Nth keyword in
-`org-todo-keywords'."
+`org-todo-keywords-1'."
(interactive "P")
(require 'calendar)
(org-compile-prefix-format 'todo)
(org-set-sorting-strategy 'todo)
+ (org-prepare-agenda "TODO")
(let* ((today (time-to-days (current-time)))
(date (calendar-gregorian-from-absolute today))
- (kwds org-todo-keywords)
+ (kwds org-todo-keywords-for-agenda)
(completion-ignore-case t)
(org-select-this-todo-keyword
(if (stringp arg) arg
(and arg (integerp arg) (> arg 0)
- (nth (1- arg) org-todo-keywords))))
+ (nth (1- arg) kwds))))
rtn rtnall files file pos)
(when (equal arg '(4))
(setq org-select-this-todo-keyword
- (completing-read "Keyword: " (mapcar 'list org-todo-keywords)
- nil t)))
+ (completing-read "Keyword (or KWD1|K2D2|...): "
+ (mapcar 'list kwds) nil nil)))
(and (equal 0 arg) (setq org-select-this-todo-keyword nil))
- (org-prepare-agenda)
(org-set-local 'org-last-arg arg)
- (org-set-local 'org-todo-keywords kwds)
(setq org-agenda-redo-command
'(org-todo-list (or current-prefix-arg org-last-arg)))
(setq files (org-agenda-files)
(setq rtnall (append rtnall rtn))))
(if org-agenda-overriding-header
(insert (org-add-props (copy-sequence org-agenda-overriding-header)
- nil 'face 'org-level-3) "\n")
+ nil 'face 'org-agenda-structure) "\n")
(insert "Global list of TODO items of type: ")
(add-text-properties (point-min) (1- (point))
- (list 'face 'org-level-3))
+ (list 'face 'org-agenda-structure))
(setq pos (point))
(insert (or org-select-this-todo-keyword "ALL") "\n")
(add-text-properties pos (1- (point)) (list 'face 'org-warning))
(setq pos (point))
(unless org-agenda-multi
- (insert
- "Available with `N r': (0)ALL "
- (let ((n 0))
- (mapconcat (lambda (x)
- (format "(%d)%s" (setq n (1+ n)) x))
- org-todo-keywords " "))
- "\n"))
- (add-text-properties pos (1- (point)) (list 'face 'org-level-3)))
+ (insert "Available with `N r': (0)ALL")
+ (let ((n 0) s)
+ (mapc (lambda (x)
+ (setq s (format "(%d)%s" (setq n (1+ n)) x))
+ (if (> (+ (current-column) (string-width s) 1) (frame-width))
+ (insert "\n "))
+ (insert " " s))
+ kwds))
+ (insert "\n"))
+ (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure)))
(when rtnall
(insert (org-finalize-agenda-entries rtnall) "\n"))
(goto-char (point-min))
buffer)
(setq matcher (org-make-tags-matcher match)
match (car matcher) matcher (cdr matcher))
- (org-prepare-agenda)
+ (org-prepare-agenda (concat "TAGS " match))
+ (setq org-agenda-query-string match)
(setq org-agenda-redo-command
(list 'org-tags-view (list 'quote todo-only)
- (list 'if 'current-prefix-arg nil match)))
+ (list 'if 'current-prefix-arg nil 'org-agenda-query-string)))
(setq files (org-agenda-files)
rtnall nil)
(while (setq file (pop files))
(with-current-buffer buffer
(unless (org-mode-p)
(error "Agenda file %s is not in `org-mode'" file))
- (setq org-category-table (org-get-category-table))
(save-excursion
(save-restriction
(if org-agenda-restrict
(setq rtnall (append rtnall rtn))))))))
(if org-agenda-overriding-header
(insert (org-add-props (copy-sequence org-agenda-overriding-header)
- nil 'face 'org-level-3) "\n")
+ nil 'face 'org-agenda-structure) "\n")
(insert "Headlines with TAGS match: ")
(add-text-properties (point-min) (1- (point))
- (list 'face 'org-level-3))
+ (list 'face 'org-agenda-structure))
(setq pos (point))
(insert match "\n")
(add-text-properties pos (1- (point)) (list 'face 'org-warning))
(setq pos (point))
(unless org-agenda-multi
(insert "Press `C-u r' to search again with new search string\n"))
- (add-text-properties pos (1- (point)) (list 'face 'org-level-3)))
+ (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure)))
(when rtnall
(insert (org-finalize-agenda-entries rtnall) "\n"))
(goto-char (point-min))
If yes, it returns the end position of this tree, causing agenda commands
to skip this subtree. This is a function that can be put into
`org-agenda-skip-function' for the duration of a command."
- (save-match-data
- (let ((end (save-excursion (org-end-of-subtree t)))
- skip)
- (save-excursion
- (setq skip (re-search-forward org-agenda-skip-regexp end t)))
- (and skip end))))
+ (let ((end (save-excursion (org-end-of-subtree t)))
+ skip)
+ (save-excursion
+ (setq skip (re-search-forward org-agenda-skip-regexp end t)))
+ (and skip end)))
+
+(defun org-agenda-skip-entry-if (&rest conditions)
+ "Skip entry if any of CONDITIONS is true.
+See `org-agenda-skip-if' for details."
+ (org-agenda-skip-if nil conditions))
+
+(defun org-agenda-skip-subtree-if (&rest conditions)
+ "Skip entry if any of CONDITIONS is true.
+See `org-agenda-skip-if' for details."
+ (org-agenda-skip-if t conditions))
+
+(defun org-agenda-skip-if (subtree conditions)
+ "Checks current entity for CONDITIONS.
+If SUBTREE is non-nil, the entire subtree is checked. Otherwise, only
+the entry, i.e. the text before the next heading is checked.
+
+CONDITIONS is a list of symbols, boolean OR is used to combine the results
+from different tests. Valid conditions are:
+
+scheduled Check if there is a scheduled cookie
+notscheduled Check if there is no scheduled cookie
+deadline Check if there is a deadline
+notdeadline Check if there is no deadline
+regexp Check if regexp matches
+notregexp Check if regexp does not match.
+
+The regexp is taken from the conditions list, it must come right after
+the `regexp' or `notregexp' element.
+
+If any of these conditions is met, this function returns the end point of
+the entity, causing the search to continue from there. This is a function
+that can be put into `org-agenda-skip-function' for the duration of a command."
+ (let (beg end m)
+ (org-back-to-heading t)
+ (setq beg (point)
+ end (if subtree
+ (progn (org-end-of-subtree t) (point))
+ (progn (outline-next-heading) (1- (point)))))
+ (goto-char beg)
+ (and
+ (or
+ (and (memq 'scheduled conditions)
+ (re-search-forward org-scheduled-time-regexp end t))
+ (and (memq 'notscheduled conditions)
+ (not (re-search-forward org-scheduled-time-regexp end t)))
+ (and (memq 'deadline conditions)
+ (re-search-forward org-deadline-time-regexp end t))
+ (and (memq 'notdeadline conditions)
+ (not (re-search-forward org-deadline-time-regexp end t)))
+ (and (setq m (memq 'regexp conditions))
+ (stringp (nth 1 m))
+ (re-search-forward (nth 1 m) end t))
+ (and (setq m (memq 'notregexp conditions))
+ (stringp (nth 1 m))
+ (not (re-search-forward (nth 1 m) end t))))
+ end)))
+;;;###autoload
(defun org-agenda-list-stuck-projects (&rest ignore)
"Create agenda view for projects that are stuck.
Stuck projects are project that have no next actions. For the definitions
MATCH is being ignored."
(interactive)
(let* ((org-agenda-skip-function 'org-agenda-skip-subtree-when-regexp-matches)
+ ;; FIXME: we could have used org-agenda-skip-if here.
(org-agenda-overriding-header "List of stuck projects: ")
(matcher (nth 0 org-stuck-projects))
(todo (nth 1 org-stuck-projects))
- (tags (nth 2 org-stuck-projects))
+ (todo-wds (if (member "*" todo)
+ (progn
+ (org-prepare-agenda-buffers (org-agenda-files))
+ (org-delete-all
+ org-done-keywords-for-agenda
+ (copy-sequence org-todo-keywords-for-agenda)))
+ todo))
(todo-re (concat "^\\*+[ \t]+\\("
- (mapconcat 'identity todo "\\|")
+ (mapconcat 'identity todo-wds "\\|")
"\\)\\>"))
- (tags-re (concat "^\\*+.*:\\("
- (mapconcat 'identity tags "\\|")
- "\\):[a-zA-Z0-9_@:]*[ \t]*$")))
-
+ (tags (nth 2 org-stuck-projects))
+ (tags-re (if (member "*" tags)
+ (org-re "^\\*+ .*:[[:alnum:]_@]+:[ \t]*$")
+ (concat "^\\*+ .*:\\("
+ (mapconcat 'identity tags "\\|")
+ (org-re "\\):[[:alnum:]_@:]*[ \t]*$"))))
+ (gen-re (nth 3 org-stuck-projects))
+ (re-list
+ (delq nil
+ (list
+ (if todo todo-re)
+ (if tags tags-re)
+ (and gen-re (stringp gen-re) (string-match "\\S-" gen-re)
+ gen-re)))))
(setq org-agenda-skip-regexp
- (cond
- ((and todo tags)
- (concat todo-re "\\|" tags-re))
- (todo todo-re)
- (tags tags-re)
- (t (error "No information how to identify unstuck projects"))))
+ (if re-list
+ (mapconcat 'identity re-list "\\|")
+ (error "No information how to identify unstuck projects")))
(org-tags-view nil matcher)
(with-current-buffer org-agenda-buffer-name
(setq org-agenda-redo-command
;;; Diary integration
(defvar org-disable-agenda-to-diary nil) ;Dynamically-scoped param.
+(defvar list-diary-entries-hook)
(defun org-get-entries-from-diary (date)
"Get the (Emacs Calendar) diary entries for DATE."
- (let* ((fancy-diary-buffer "*temporary-fancy-diary-buffer*")
+ (require 'diary-lib)
+ (let* ((diary-fancy-buffer "*temporary-fancy-diary-buffer*")
+ (fancy-diary-buffer diary-fancy-buffer)
(diary-display-hook '(fancy-diary-display))
+ (pop-up-frames nil)
(list-diary-entries-hook
(cons 'org-diary-default-entry list-diary-entries-hook))
(diary-file-name-prefix-function nil) ; turn this feature off
(org-disable-agenda-to-diary t))
(save-excursion
(save-window-excursion
- (list-diary-entries date 1))) ;; Keep this name for now, compatibility
- (if (not (get-buffer fancy-diary-buffer))
+ (funcall (if (fboundp 'diary-list-entries)
+ 'diary-list-entries 'list-diary-entries)
+ date 1)))
+ (if (not (get-buffer diary-fancy-buffer))
(setq entries nil)
- (with-current-buffer fancy-diary-buffer
+ (with-current-buffer diary-fancy-buffer
(setq buffer-read-only nil)
- (if (= (point-max) 1)
+ (if (zerop (buffer-size))
;; No entries
(setq entries nil)
;; Omit the date and other unnecessary stuff
(org-agenda-cleanup-fancy-diary)
;; Add prefix to each line and extend the text properties
- (if (= (point-max) 1)
+ (if (zerop (buffer-size))
(setq entries nil)
(setq entries (buffer-substring (point-min) (- (point-max) 1)))))
(set-buffer-modified-p nil)
- (kill-buffer fancy-diary-buffer)))
+ (kill-buffer diary-fancy-buffer)))
(when entries
(setq entries (org-split-string entries "\n"))
(setq entries
(lambda (x)
(setq x (org-format-agenda-item "" x "Diary" nil 'time))
;; Extend the text properties to the beginning of the line
- (org-add-props x (text-properties-at (1- (length x)) x)))
+ (org-add-props x (text-properties-at (1- (length x)) x)
+ 'type "diary" 'date date))
entries)))))
(defun org-agenda-cleanup-fancy-diary ()
(org-add-props string nil
'mouse-face 'highlight
'keymap org-agenda-keymap
- 'help-echo (format "mouse-2 or RET jump to diary file %s"
- (abbreviate-file-name buffer-file-name))
+ 'help-echo (if buffer-file-name
+ (format "mouse-2 or RET jump to diary file %s"
+ (abbreviate-file-name buffer-file-name))
+ "")
'org-agenda-diary-link t
'org-marker (org-agenda-new-marker (point-at-bol))))
date range matching the selected date. Deadlines will
also be listed, on the expiration day.
+ :sexp List entries resulting from diary-like sexps.
+
:deadline List any deadlines past due, or due within
`org-deadline-warning-days'. The listing occurs only
in the diary for *today*, not at any other date. If
&%%(org-diary)
If you don't give any arguments (as in the example above), the default
-arguments (:deadline :scheduled :timestamp) are used. So the example above may
-also be written as
+arguments (:deadline :scheduled :timestamp :sexp) are used.
+So the example above may also be written as
- &%%(org-diary :deadline :timestamp :scheduled)
+ &%%(org-diary :deadline :timestamp :sexp :scheduled)
The function expects the lisp variables `entry' and `date' to be provided
by the caller, because this is how the calendar works. Don't use this
function from a program - use `org-agenda-get-day-entries' instead."
- (org-agenda-maybe-reset-markers)
+ (when (> (- (time-to-seconds (current-time))
+ org-agenda-last-marker-time)
+ 5)
+ (org-agenda-reset-markers))
(org-compile-prefix-format 'agenda)
(org-set-sorting-strategy 'agenda)
- (setq args (or args '(:deadline :scheduled :timestamp)))
+ (setq args (or args '(:deadline :scheduled :timestamp :sexp)))
(let* ((files (if (and entry (stringp entry) (string-match "\\S-" entry))
(list entry)
(org-agenda-files t)))
file rtn results)
+ (org-prepare-agenda-buffers files)
;; If this is called during org-agenda, don't return any entries to
;; the calendar. Org Agenda will list these entries itself.
(if org-disable-agenda-to-diary (setq files nil))
the one returned by `calendar-current-date'. ARGS are symbols indicating
which kind of entries should be extracted. For details about these, see
the documentation of `org-diary'."
- (setq args (or args '(:deadline :scheduled :timestamp)))
+ (setq args (or args '(:deadline :scheduled :timestamp :sexp)))
(let* ((org-startup-folded nil)
(org-startup-align-all-tables nil)
(buffer (if (file-exists-p file)
(with-current-buffer buffer
(unless (org-mode-p)
(error "Agenda file %s is not in `org-mode'" file))
- (setq org-category-table (org-get-category-table))
(let ((case-fold-search nil))
(save-excursion
(save-restriction
(setq results (append results rtn))
(setq rtn (org-agenda-get-timestamps))
(setq results (append results rtn)))
+ ((eq arg :sexp)
+ (setq rtn (org-agenda-get-sexps))
+ (setq results (append results rtn)))
((eq arg :scheduled)
(setq rtn (org-agenda-get-scheduled))
(setq results (append results rtn)))
((eq arg :closed)
(setq rtn (org-agenda-get-closed))
(setq results (append results rtn)))
- ((and (eq arg :deadline)
- (equal date (calendar-current-date)))
+ ((eq arg :deadline)
(setq rtn (org-agenda-get-deadlines))
(setq results (append results rtn))))))))
results))))
+(defun org-entry-is-todo-p ()
+ (member (org-get-todo-state) org-not-done-keywords))
+
(defun org-entry-is-done-p ()
- "Is the current entry marked DONE?"
+ (member (org-get-todo-state) org-done-keywords))
+
+(defun org-get-todo-state ()
(save-excursion
- (and (re-search-backward "[\r\n]\\*" nil t)
- (looking-at org-nl-done-regexp))))
+ (org-back-to-heading t)
+ (and (looking-at org-todo-line-regexp)
+ (match-end 2)
+ (match-string 2))))
(defun org-at-date-range-p (&optional inactive-ok)
"Is the cursor inside a date range?"
(let* ((props (list 'face nil
'done-face 'org-done
'org-not-done-regexp org-not-done-regexp
+ 'org-todo-regexp org-todo-regexp
'mouse-face 'highlight
'keymap org-agenda-keymap
'help-echo
(format "mouse-2 or RET jump to org file %s"
(abbreviate-file-name buffer-file-name))))
- (regexp (concat "[\n\r]\\*+ *\\("
+ ;; FIXME: get rid of the \n at some point but watch out
+ (regexp (concat "^\\*+[ \t]+\\("
(if org-select-this-todo-keyword
- (concat "\\<\\(" org-select-this-todo-keyword
- "\\)\\>")
+ (if (equal org-select-this-todo-keyword "*")
+ org-todo-regexp
+ (concat "\\<\\("
+ (mapconcat 'identity (org-split-string org-select-this-todo-keyword "|") "\\|")
+ "\\)\\>"))
org-not-done-regexp)
"[^\n\r]*\\)"))
marker priority category tags
(save-match-data
(beginning-of-line)
(setq beg (point) end (progn (outline-next-heading) (point)))
- (when (or (and org-agenda-todo-ignore-scheduled (goto-char beg)
+ (when (or (and org-agenda-todo-ignore-with-date (goto-char beg)
+ (re-search-forward org-ts-regexp end t))
+ (and org-agenda-todo-ignore-scheduled (goto-char beg)
(re-search-forward org-scheduled-time-regexp end t))
(and org-agenda-todo-ignore-deadlines (goto-char beg)
(re-search-forward org-deadline-time-regexp end t)
(org-deadline-close (match-string 1))))
- (goto-char beg)
+ (goto-char (1+ beg))
(or org-agenda-todo-list-sublevels (org-end-of-subtree 'invisible))
(throw :skip nil)))
(goto-char beg)
(org-agenda-skip)
(goto-char (match-beginning 1))
- (setq marker (org-agenda-new-marker (1+ (match-beginning 0)))
+ (setq marker (org-agenda-new-marker (match-beginning 0))
category (org-get-category)
tags (org-get-tags-at (point))
txt (org-format-agenda-item "" (match-string 1) category tags)
- priority
- (+ (org-get-priority txt)
- (if org-todo-kwd-priority-p
- (- org-todo-kwd-max-priority -2
- (length
- (member (match-string 2) org-todo-keywords)))
- 1)))
+ priority (1+ (org-get-priority txt)))
(org-add-props txt props
'org-marker marker 'org-hd-marker marker
- 'priority priority 'org-category category)
+ 'priority priority 'org-category category
+ 'type "todo")
(push txt ee)
(if org-agenda-todo-list-sublevels
(goto-char (match-end 1))
"Return the date stamp information for agenda display."
(let* ((props (list 'face nil
'org-not-done-regexp org-not-done-regexp
+ 'org-todo-regexp org-todo-regexp
'mouse-face 'highlight
'keymap org-agenda-keymap
'help-echo
(format "mouse-2 or RET jump to org file %s"
(abbreviate-file-name buffer-file-name))))
- (regexp (regexp-quote
- (substring
- (format-time-string
- (car org-time-stamp-formats)
- (apply 'encode-time ; DATE bound by calendar
- (list 0 0 0 (nth 1 date) (car date) (nth 2 date))))
- 0 11)))
+ (d1 (calendar-absolute-from-gregorian date))
+ (remove-re
+ (concat
+ (regexp-quote
+ (format-time-string
+ "<%Y-%m-%d"
+ (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date))))
+ ".*?>"))
+ (regexp
+ (concat
+ (regexp-quote
+ (substring
+ (format-time-string
+ (car org-time-stamp-formats)
+ (apply 'encode-time ; DATE bound by calendar
+ (list 0 0 0 (nth 1 date) (car date) (nth 2 date))))
+ 0 11))
+ "\\|\\(<[0-9]+-[0-9]+-[0-9]+[^>\n]+?\\+[0-9]+[dwmy]>\\)"
+ "\\|\\(<%%\\(([^>\n]+)\\)>\\)"))
marker hdmarker deadlinep scheduledp donep tmp priority category
- ee txt timestr tags)
+ ee txt timestr tags b0 b3 e3 head)
(goto-char (point-min))
(while (re-search-forward regexp nil t)
+ (setq b0 (match-beginning 0)
+ b3 (match-beginning 3) e3 (match-end 3))
(catch :skip
- (and (save-match-data (org-at-date-range-p)) (throw :skip nil))
+ (and (org-at-date-range-p) (throw :skip nil))
(org-agenda-skip)
- (setq marker (org-agenda-new-marker (match-beginning 0))
- category (org-get-category (match-beginning 0))
+ (if (and (match-end 1)
+ (not (= d1 (org-time-string-to-absolute (match-string 1) d1))))
+ (throw :skip nil))
+ (if (and e3
+ (not (org-diary-sexp-entry (buffer-substring b3 e3) "" date)))
+ (throw :skip nil))
+ (setq marker (org-agenda-new-marker b0)
+ category (org-get-category b0)
tmp (buffer-substring (max (point-min)
- (- (match-beginning 0)
- org-ds-keyword-length))
- (match-beginning 0))
- timestr (buffer-substring (match-beginning 0) (point-at-eol))
+ (- b0 org-ds-keyword-length))
+ b0)
+ timestr (if b3 "" (buffer-substring b0 (point-at-eol)))
deadlinep (string-match org-deadline-regexp tmp)
scheduledp (string-match org-scheduled-regexp tmp)
donep (org-entry-is-done-p))
- (and org-agenda-skip-scheduled-if-done
- scheduledp donep
- (throw :skip t))
+ (if (or scheduledp deadlinep) (throw :skip t))
(if (string-match ">" timestr)
;; substring should only run to end of time stamp
(setq timestr (substring timestr 0 (match-end 0))))
(save-excursion
- (if (re-search-backward "\\(^\\|\r\\)\\*+" nil t)
+ (if (re-search-backward "^\\*+ " nil t)
(progn
- (goto-char (match-end 1))
+ (goto-char (match-beginning 0))
(setq hdmarker (org-agenda-new-marker)
tags (org-get-tags-at))
- (looking-at "\\*+[ \t]*\\([^\r\n]+\\)")
+ (looking-at "\\*+[ \t]+\\([^\r\n]+\\)")
+ (setq head (match-string 1))
+ (and org-agenda-skip-timestamp-if-done donep (throw :skip t))
(setq txt (org-format-agenda-item
- (format "%s%s"
- (if deadlinep "Deadline: " "")
- (if scheduledp "Scheduled: " ""))
- (match-string 1) category tags timestr)))
+ nil head category tags timestr nil
+ remove-re)))
(setq txt org-agenda-no-heading-message))
(setq priority (org-get-priority txt))
(org-add-props txt props
'org-marker marker 'org-hd-marker hdmarker)
- (if deadlinep
- (org-add-props txt nil
- 'face (if donep 'org-done 'org-warning)
- 'undone-face 'org-warning 'done-face 'org-done
- 'org-category category 'priority (+ 100 priority))
- (if scheduledp
- (org-add-props txt nil
- 'face 'org-scheduled-today
- 'undone-face 'org-scheduled-today 'done-face 'org-done
- 'org-category category 'priority (+ 99 priority))
- (org-add-props txt nil 'priority priority 'org-category category)))
+ (org-add-props txt nil 'priority priority
+ 'org-category category 'date date
+ 'type "timestamp")
(push txt ee))
(outline-next-heading)))
(nreverse ee)))
+(defun org-agenda-get-sexps ()
+ "Return the sexp information for agenda display."
+ (require 'diary-lib)
+ (let* ((props (list 'face nil
+ 'mouse-face 'highlight
+ 'keymap org-agenda-keymap
+ 'help-echo
+ (format "mouse-2 or RET jump to org file %s"
+ (abbreviate-file-name buffer-file-name))))
+ (regexp "^&?%%(")
+ marker category ee txt tags entry result beg b sexp sexp-entry)
+ (goto-char (point-min))
+ (while (re-search-forward regexp nil t)
+ (catch :skip
+ (org-agenda-skip)
+ (setq beg (match-beginning 0))
+ (goto-char (1- (match-end 0)))
+ (setq b (point))
+ (forward-sexp 1)
+ (setq sexp (buffer-substring b (point)))
+ (setq sexp-entry (if (looking-at "[ \t]*\\(\\S-.*\\)")
+ (org-trim (match-string 1))
+ ""))
+ (setq result (org-diary-sexp-entry sexp sexp-entry date))
+ (when result
+ (setq marker (org-agenda-new-marker beg)
+ category (org-get-category beg))
+
+ (if (string-match "\\S-" result)
+ (setq txt result)
+ (setq txt "SEXP entry returned empty string"))
+
+ (setq txt (org-format-agenda-item
+ "" txt category tags 'time))
+ (org-add-props txt props 'org-marker marker)
+ (org-add-props txt nil
+ 'org-category category 'date date
+ 'type "sexp")
+ (push txt ee))))
+ (nreverse ee)))
+
(defun org-agenda-get-closed ()
"Return the logged TODO entries for agenda display."
(let* ((props (list 'mouse-face 'highlight
'org-not-done-regexp org-not-done-regexp
+ 'org-todo-regexp org-todo-regexp
'keymap org-agenda-keymap
'help-echo
(format "mouse-2 or RET jump to org file %s"
;; substring should only run to end of time stamp
(setq timestr (substring timestr 0 (match-end 0))))
(save-excursion
- (if (re-search-backward "\\(^\\|\r\\)\\*+" nil t)
+ (if (re-search-backward "^\\*+ " nil t)
(progn
- (goto-char (match-end 1))
+ (goto-char (match-beginning 0))
(setq hdmarker (org-agenda-new-marker)
tags (org-get-tags-at))
- (looking-at "\\*+[ \t]*\\([^\r\n]+\\)")
+ (looking-at "\\*+[ \t]+\\([^\r\n]+\\)")
(setq txt (org-format-agenda-item
(if closedp "Closed: " "Clocked: ")
(match-string 1) category tags timestr)))
(org-add-props txt props
'org-marker marker 'org-hd-marker hdmarker 'face 'org-done
'priority priority 'org-category category
+ 'type "closed" 'date date
'undone-face 'org-warning 'done-face 'org-done)
(push txt ee))
- (outline-next-heading)))
+ (goto-char (point-at-eol))))
(nreverse ee)))
(defun org-agenda-get-deadlines ()
"Return the deadline information for agenda display."
- (let* ((wdays org-deadline-warning-days)
- (props (list 'mouse-face 'highlight
+ (let* ((props (list 'mouse-face 'highlight
'org-not-done-regexp org-not-done-regexp
+ 'org-todo-regexp org-todo-regexp
'keymap org-agenda-keymap
'help-echo
(format "mouse-2 or RET jump to org file %s"
(regexp org-deadline-time-regexp)
(todayp (equal date (calendar-current-date))) ; DATE bound by calendar
(d1 (calendar-absolute-from-gregorian date)) ; DATE bound by calendar
- d2 diff pos pos1 category tags
- ee txt head face)
+ d2 diff dfrac wdays pos pos1 category tags
+ ee txt head face s upcomingp donep timestr)
(goto-char (point-min))
(while (re-search-forward regexp nil t)
(catch :skip
(org-agenda-skip)
- (setq pos (1- (match-beginning 1))
- d2 (time-to-days
- (org-time-string-to-time (match-string 1)))
- diff (- d2 d1))
+ (setq s (match-string 1)
+ pos (1- (match-beginning 1))
+ d2 (org-time-string-to-absolute (match-string 1) d1 'past)
+ diff (- d2 d1)
+ wdays (org-get-wdays s)
+ dfrac (/ (* 1.0 (- wdays diff)) (max wdays 1))
+ upcomingp (and todayp (> diff 0)))
;; When to show a deadline in the calendar:
;; If the expiration is within wdays warning time.
;; Past-due deadlines are only shown on the current date
- (if (and (< diff wdays) todayp (not (= diff 0)))
+ (if (or (and (<= diff wdays)
+ (and todayp (not org-agenda-only-exact-dates)))
+ (= diff 0))
(save-excursion
(setq category (org-get-category))
- (if (re-search-backward "\\(^\\|\r\\)\\*+[ \t]*" nil t)
+ (if (re-search-backward "^\\*+[ \t]+" nil t)
(progn
(goto-char (match-end 0))
- (setq pos1 (match-end 1))
+ (setq pos1 (match-beginning 0))
(setq tags (org-get-tags-at pos1))
(setq head (buffer-substring-no-properties
(point)
(progn (skip-chars-forward "^\r\n")
(point))))
- (if (string-match org-looking-at-done-regexp head)
+ (setq donep (string-match org-looking-at-done-regexp head))
+ (if (string-match " \\([012]?[0-9]:[0-9][0-9]\\)" s)
+ (setq timestr
+ (concat (substring s (match-beginning 1)) " "))
+ (setq timestr 'time))
+ (if (and donep
+ (or org-agenda-skip-deadline-if-done
+ (not (= diff 0))))
(setq txt nil)
(setq txt (org-format-agenda-item
- (format "In %3d d.: " diff) head category tags))))
+ (if (= diff 0)
+ (car org-agenda-deadline-leaders)
+ (format (nth 1 org-agenda-deadline-leaders)
+ diff))
+ head category tags timestr))))
(setq txt org-agenda-no-heading-message))
(when txt
- (setq face (cond ((<= diff 0) 'org-warning)
- ((<= diff 5) 'org-upcoming-deadline)
- (t nil)))
+ (setq face (org-agenda-deadline-face dfrac wdays))
(org-add-props txt props
'org-marker (org-agenda-new-marker pos)
'org-hd-marker (org-agenda-new-marker pos1)
- 'priority (+ (- 10 diff) (org-get-priority txt))
+ 'priority (+ (- diff)
+ (org-get-priority txt))
'org-category category
- 'face face 'undone-face face 'done-face 'org-done)
+ 'type (if upcomingp "upcoming-deadline" "deadline")
+ 'date (if upcomingp date d2)
+ 'face (if donep 'org-done face)
+ 'undone-face face 'done-face 'org-done)
(push txt ee))))))
- ee))
+ (nreverse ee)))
+
+(defun org-agenda-deadline-face (fraction &optional wdays)
+ "Return the face to displaying a deadline item.
+FRACTION is what fraction of the head-warning time has passed."
+ (if (equal wdays 0) (setq fraction 1.))
+ (let ((faces org-agenda-deadline-faces) f)
+ (catch 'exit
+ (while (setq f (pop faces))
+ (if (>= fraction (car f)) (throw 'exit (cdr f)))))))
(defun org-agenda-get-scheduled ()
"Return the scheduled information for agenda display."
- (let* ((props (list 'face 'org-scheduled-previously
- 'org-not-done-regexp org-not-done-regexp
- 'undone-face 'org-scheduled-previously
+ (let* ((props (list 'org-not-done-regexp org-not-done-regexp
+ 'org-todo-regexp org-todo-regexp
'done-face 'org-done
'mouse-face 'highlight
'keymap org-agenda-keymap
(todayp (equal date (calendar-current-date))) ; DATE bound by calendar
(d1 (calendar-absolute-from-gregorian date)) ; DATE bound by calendar
d2 diff pos pos1 category tags
- ee txt head)
+ ee txt head pastschedp donep face timestr s)
(goto-char (point-min))
(while (re-search-forward regexp nil t)
(catch :skip
(org-agenda-skip)
- (setq pos (1- (match-beginning 1))
- d2 (time-to-days
- (org-time-string-to-time (match-string 1)))
+ (setq s (match-string 1)
+ pos (1- (match-beginning 1))
+ d2 (org-time-string-to-absolute (match-string 1) d1 'past)
+;;; is this right?
+;;; do we need to do this for deadleine too????
+;;; d2 (org-time-string-to-absolute (match-string 1) (if todayp nil d1))
diff (- d2 d1))
+ (setq pastschedp (and todayp (< diff 0)))
;; When to show a scheduled item in the calendar:
;; If it is on or past the date.
- (if (and (< diff 0) todayp)
+ (if (or (and (< diff 0)
+ (and todayp (not org-agenda-only-exact-dates)))
+ (= diff 0))
(save-excursion
(setq category (org-get-category))
- (if (re-search-backward "\\(^\\|\r\\)\\*+[ \t]*" nil t)
+ (if (re-search-backward "^\\*+[ \t]+" nil t)
(progn
(goto-char (match-end 0))
- (setq pos1 (match-end 1))
+ (setq pos1 (match-beginning 0))
(setq tags (org-get-tags-at))
(setq head (buffer-substring-no-properties
(point)
(progn (skip-chars-forward "^\r\n") (point))))
- (if (string-match org-looking-at-done-regexp head)
+ (setq donep (string-match org-looking-at-done-regexp head))
+ (if (string-match " \\([012]?[0-9]:[0-9][0-9]\\)" s)
+ (setq timestr
+ (concat (substring s (match-beginning 1)) " "))
+ (setq timestr 'time))
+ (if (and donep
+ (or org-agenda-skip-scheduled-if-done
+ (not (= diff 0))))
(setq txt nil)
(setq txt (org-format-agenda-item
- (format "Sched.%2dx: " (- 1 diff)) head
- category tags))))
+ (if (= diff 0)
+ (car org-agenda-scheduled-leaders)
+ (format (nth 1 org-agenda-scheduled-leaders)
+ (- 1 diff)))
+ head category tags timestr))))
(setq txt org-agenda-no-heading-message))
(when txt
+ (setq face (if pastschedp
+ 'org-scheduled-previously
+ 'org-scheduled-today))
(org-add-props txt props
+ 'undone-face face
+ 'face (if donep 'org-done face)
'org-marker (org-agenda-new-marker pos)
'org-hd-marker (org-agenda-new-marker pos1)
- 'priority (+ (- 5 diff) (org-get-priority txt))
+ 'type (if pastschedp "past-scheduled" "scheduled")
+ 'date (if pastschedp d2 date)
+ 'priority (+ 94 (- 5 diff) (org-get-priority txt))
'org-category category)
(push txt ee))))))
- ee))
+ (nreverse ee)))
(defun org-agenda-get-blocks ()
"Return the date-range information for agenda display."
(let* ((props (list 'face nil
'org-not-done-regexp org-not-done-regexp
+ 'org-todo-regexp org-todo-regexp
'mouse-face 'highlight
'keymap org-agenda-keymap
'help-echo
(abbreviate-file-name buffer-file-name))))
(regexp org-tr-regexp)
(d0 (calendar-absolute-from-gregorian date))
- marker hdmarker ee txt d1 d2 s1 s2 timestr category tags pos)
+ marker hdmarker ee txt d1 d2 s1 s2 timestr category tags pos
+ donep head)
(goto-char (point-min))
(while (re-search-forward regexp nil t)
(catch :skip
(save-excursion
(setq marker (org-agenda-new-marker (point)))
(setq category (org-get-category))
- (if (re-search-backward "\\(^\\|\r\\)\\*+" nil t)
+ (if (re-search-backward "^\\*+ " nil t)
(progn
- (setq hdmarker (org-agenda-new-marker (match-end 1)))
- (goto-char (match-end 1))
+ (goto-char (match-beginning 0))
+ (setq hdmarker (org-agenda-new-marker (point)))
(setq tags (org-get-tags-at))
- (looking-at "\\*+[ \t]*\\([^\r\n]+\\)")
+ (looking-at "\\*+[ \t]+\\([^\r\n]+\\)")
+ (setq head (match-string 1))
+ (and org-agenda-skip-timestamp-if-done
+ (org-entry-is-done-p)
+ (throw :skip t))
(setq txt (org-format-agenda-item
(format (if (= d1 d2) "" "(%d/%d): ")
(1+ (- d0 d1)) (1+ (- d2 d1)))
- (match-string 1) category tags
+ head category tags
(if (= d0 d1) timestr))))
(setq txt org-agenda-no-heading-message))
(org-add-props txt props
'org-marker marker 'org-hd-marker hdmarker
+ 'type "block" 'date date
'priority (org-get-priority txt) 'org-category category)
(push txt ee)))
(goto-char pos)))
;;; Agenda presentation and sorting
-;; FIXME: should I allow spaces around the dash?
(defconst org-plain-time-of-day-regexp
(concat
"\\(\\<[012]?[0-9]"
Examples: 11:45 or 8am-13:15 or 2:45-2:45pm. After a match, the following
groups carry important information:
0 the full match
-1 the first time, range or not
-8 the second time, if it is a range.")
+1 the first time, range or not
+8 the second time, if it is a range.")
+
+(defconst org-plain-time-extension-regexp
+ (concat
+ "\\(\\<[012]?[0-9]"
+ "\\(\\(:\\([0-5][0-9]\\([AaPp][Mm]\\)?\\)\\)\\|\\([AaPp][Mm]\\)\\)\\>\\)"
+ "\\+\\([0-9]+\\)\\(:\\([0-5][0-9]\\)\\)?")
+ "Regular expression to match a time range like 13:30+2:10 = 13:30-15:40.
+Examples: 11:45 or 8am-13:15 or 2:45-2:45pm. After a match, the following
+groups carry important information:
+0 the full match
+7 hours of duration
+9 minutes of duration")
(defconst org-stamp-time-of-day-regexp
(concat
"<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} +\\sw+ +\\)"
- "\\([012][0-9]:[0-5][0-9]\\)>"
+ "\\([012][0-9]:[0-5][0-9]\\(-\\([012][0-9]:[0-5][0-9]\\)\\)?[^\n\r>]*?\\)>"
"\\(--?"
"<\\1\\([012][0-9]:[0-5][0-9]\\)>\\)?")
"Regular expression to match a timestamp time or time range.
The flag is set if the currently compiled format contains a `%T'.")
(defun org-format-agenda-item (extra txt &optional category tags dotime
- noprefix)
+ noprefix remove-re)
"Format TXT to be inserted into the agenda buffer.
In particular, it adds the prefix and corresponding text properties. EXTRA
must be a string and replaces the `%s' specifier in the prefix format.
the `%t' specifier in the format. When DOTIME is a string, this string is
searched for a time before TXT is. NOPREFIX is a flag and indicates that
only the correctly processes TXT should be returned - this is used by
-`org-agenda-change-all-lines'. TAGS can be the tags of the headline."
+`org-agenda-change-all-lines'. TAGS can be the tags of the headline.
+Any match of REMOVE-RE will be removed from TXT."
(save-match-data
;; Diary entries sometimes have extra whitespace at the beginning
(if (string-match "^ +" txt) (setq txt (replace-match "" nil nil txt)))
time ; time and tag are needed for the eval of the prefix format
(ts (if dotime (concat (if (stringp dotime) dotime "") txt)))
(time-of-day (and dotime (org-get-time-of-day ts)))
- stamp plain s0 s1 s2 rtn)
+ stamp plain s0 s1 s2 rtn srp)
(when (and dotime time-of-day org-prefix-has-time)
;; Extract starting and ending time and move them to prefix
(when (or (setq stamp (string-match org-stamp-time-of-day-regexp ts))
(setq plain (string-match org-plain-time-of-day-regexp ts)))
(setq s0 (match-string 0 ts)
+ srp (and stamp (match-end 3))
s1 (match-string (if plain 1 2) ts)
- s2 (match-string (if plain 8 4) ts))
+ s2 (match-string (if plain 8 (if srp 4 6)) ts))
;; If the times are in TXT (not in DOTIMES), and the prefix will list
;; them, we might want to remove them there to avoid duplication.
;; The user can turn this off with a variable.
(if (and org-agenda-remove-times-when-in-prefix (or stamp plain)
(string-match (concat (regexp-quote s0) " *") txt)
+ (not (equal ?\] (string-to-char (substring txt (match-end 0)))))
(if (eq org-agenda-remove-times-when-in-prefix 'beg)
(= (match-beginning 0) 0)
t))
(if s1 (setq s1 (org-get-time-of-day s1 'string t)))
(if s2 (setq s2 (org-get-time-of-day s2 'string t))))
- (when (string-match "\\([ \t]+\\)\\(:[a-zA-Z_@0-9:]+:\\)[ \t]*$" txt)
+ (when (and s1 (not s2) org-agenda-default-appointment-duration
+ (string-match "\\([0-9]+\\):\\([0-9]+\\)" s1))
+ (let ((m (+ (string-to-number (match-string 2 s1))
+ (* 60 (string-to-number (match-string 1 s1)))
+ org-agenda-default-appointment-duration))
+ h)
+ (setq h (/ m 60) m (- m (* h 60)))
+ (setq s2 (format "%02d:%02d" h m))))
+
+ (when (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@:]+:\\)[ \t]*$")
+ txt)
;; Tags are in the string
- (if (or (eq org-agenda-remove-tags-when-in-prefix t)
- (and org-agenda-remove-tags-when-in-prefix
+ (if (or (eq org-agenda-remove-tags t)
+ (and org-agenda-remove-tags
org-prefix-has-tag))
(setq txt (replace-match "" t t txt))
(setq txt (replace-match
(match-string 2 txt))
t t txt))))
+ (when remove-re
+ (while (string-match remove-re txt)
+ (setq txt (replace-match "" t t txt))))
+
;; Create the final string
(if noprefix
(setq rtn txt)
;; And finally add the text properties
(org-add-props rtn nil
'org-category (downcase category) 'tags tags
+ 'org-highest-priority org-highest-priority
+ 'org-lowest-priority org-lowest-priority
'prefix-length (- (length rtn) (length txt))
'time-of-day time-of-day
+ 'txt txt
+ 'time time
+ 'extra extra
'dotime dotime))))
-(defvar org-agenda-sorting-strategy)
+(defvar org-agenda-sorting-strategy) ;; because the def is in a let form
(defvar org-agenda-sorting-strategy-selected nil)
(defun org-agenda-add-time-grid-maybe (list ndays todayp)
HH:MM."
(save-match-data
(when
- (or
- (string-match
- "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)\\([AaPp][Mm]\\)?\\> *" s)
- (string-match
- "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?\\([AaPp][Mm]\\)\\> *" s))
+ (or (string-match "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)\\([AaPp][Mm]\\)?\\> *" s)
+ (string-match "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?\\([AaPp][Mm]\\)\\> *" s))
(let* ((h (string-to-number (match-string 1 s)))
(m (if (match-end 3) (string-to-number (match-string 3 s)) 0))
(ampm (if (match-end 4) (downcase (match-string 4 s))))
(if (eq x 'line)
(save-excursion
(beginning-of-line 1)
- (setq re (get-text-property (point) 'org-not-done-regexp))
+ (setq re (get-text-property (point) 'org-todo-regexp))
(goto-char (+ (point) (or (get-text-property (point) 'prefix-length) 0)))
- (and (looking-at (concat "[ \t]*\\.*" re))
- (add-text-properties (match-beginning 0) (match-end 0)
- '(face org-todo))))
- (setq re (concat (get-text-property 0 'org-not-done-regexp x))
+ (when (looking-at (concat "[ \t]*\\.*" re " +"))
+ (add-text-properties (match-beginning 0) (match-end 0)
+ (list 'face (org-get-todo-face 0)))
+ (let ((s (buffer-substring (match-beginning 1) (match-end 1))))
+ (delete-region (match-beginning 1) (1- (match-end 0)))
+ (goto-char (match-beginning 1))
+ (insert (format org-agenda-todo-keyword-format s)))))
+ (setq re (concat (get-text-property 0 'org-todo-regexp x))
pl (get-text-property 0 'prefix-length x))
- (and re (equal (string-match (concat "\\(\\.*\\)" re) x (or pl 0)) pl)
- (add-text-properties (or (match-end 1) (match-end 0)) (match-end 0)
- '(face org-todo) x))
+ (when (and re
+ (equal (string-match (concat "\\(\\.*\\)" re "\\( +\\)")
+ x (or pl 0)) pl))
+ (add-text-properties
+ (or (match-end 1) (match-end 0)) (match-end 0)
+ (list 'face (org-get-todo-face (match-string 2 x)))
+ x)
+ (setq x (concat (substring x 0 (match-end 1))
+ (format org-agenda-todo-keyword-format
+ (match-string 2 x))
+ " "
+ (substring x (match-end 3)))))
x)))
(defsubst org-cmp-priority (a b)
(defsubst org-cmp-category (a b)
"Compare the string values of categories of strings A and B."
- (let ((ca (or (get-text-property 1 'category a) ""))
- (cb (or (get-text-property 1 'category b) "")))
+ (let ((ca (or (get-text-property 1 'org-category a) ""))
+ (cb (or (get-text-property 1 'org-category b) "")))
(cond ((string-lessp ca cb) -1)
((string-lessp cb ca) +1)
(t nil))))
(eval (cons 'or org-agenda-sorting-strategy-selected))
'((-1 . t) (1 . nil) (nil . nil))))))
+;;; Agenda restriction lock
+
+(defvar org-agenda-restriction-lock-overlay (org-make-overlay 1 1)
+ "Overlay to mark the headline to which arenda commands are restricted.")
+(org-overlay-put org-agenda-restriction-lock-overlay
+ 'face 'org-agenda-restriction-lock)
+(org-overlay-put org-agenda-restriction-lock-overlay
+ 'help-echo "Agendas are currently limited to this subtree.")
+(org-detach-overlay org-agenda-restriction-lock-overlay)
+(defvar org-speedbar-restriction-lock-overlay (org-make-overlay 1 1)
+ "Overlay marking the agenda restriction line in speedbar.")
+(org-overlay-put org-speedbar-restriction-lock-overlay
+ 'face 'org-agenda-restriction-lock)
+(org-overlay-put org-speedbar-restriction-lock-overlay
+ 'help-echo "Agendas are currently limited to this item.")
+(org-detach-overlay org-speedbar-restriction-lock-overlay)
+
+(defun org-agenda-set-restriction-lock (&optional type)
+ "Set restriction lock for agenda, to current subtree or file.
+Restriction will be the file if TYPE is `file', or if type is the
+universal prefix '(4), or if the cursor is before the first headline
+in the file. Otherwise, restriction will be to the current subtree."
+ (interactive "P")
+ (and (equal type '(4)) (setq type 'file))
+ (setq type (cond
+ (type type)
+ ((org-at-heading-p) 'subtree)
+ ((condition-case nil (org-back-to-heading t) (error nil))
+ 'subtree)
+ (t 'file)))
+ (if (eq type 'subtree)
+ (progn
+ (setq org-agenda-restrict t)
+ (setq org-agenda-overriding-restriction 'subtree)
+ (put 'org-agenda-files 'org-restrict
+ (list (buffer-file-name (buffer-base-buffer))))
+ (org-back-to-heading t)
+ (org-move-overlay org-agenda-restriction-lock-overlay (point) (point-at-eol))
+ (move-marker org-agenda-restrict-begin (point))
+ (move-marker org-agenda-restrict-end
+ (save-excursion (org-end-of-subtree t)))
+ (message "Locking agenda restriction to subtree"))
+ (put 'org-agenda-files 'org-restrict
+ (list (buffer-file-name (buffer-base-buffer))))
+ (setq org-agenda-restrict nil)
+ (setq org-agenda-overriding-restriction 'file)
+ (move-marker org-agenda-restrict-begin nil)
+ (move-marker org-agenda-restrict-end nil)
+ (message "Locking agenda restriction to file"))
+ (setq current-prefix-arg nil)
+ (org-agenda-maybe-redo))
+
+(defun org-agenda-remove-restriction-lock (&optional noupdate)
+ "Remove the agenda restriction lock."
+ (interactive "P")
+ (org-detach-overlay org-agenda-restriction-lock-overlay)
+ (org-detach-overlay org-speedbar-restriction-lock-overlay)
+ (setq org-agenda-overriding-restriction nil)
+ (setq org-agenda-restrict nil)
+ (put 'org-agenda-files 'org-restrict nil)
+ (move-marker org-agenda-restrict-begin nil)
+ (move-marker org-agenda-restrict-end nil)
+ (setq current-prefix-arg nil)
+ (message "Agenda restriction lock removed")
+ (or noupdate (org-agenda-maybe-redo)))
+
+(defun org-agenda-maybe-redo ()
+ "If there is any window showing the agenda view, update it."
+ (let ((w (get-buffer-window org-agenda-buffer-name t))
+ (w0 (selected-window)))
+ (when w
+ (select-window w)
+ (org-agenda-redo)
+ (select-window w0)
+ (if org-agenda-overriding-restriction
+ (message "Agenda view shifted to new %s restriction"
+ org-agenda-overriding-restriction)
+ (message "Agenda restriction lock removed")))))
+
;;; Agenda commands
(defun org-agenda-check-type (error &rest types)
(let ((buf (current-buffer)))
(if (not (one-window-p)) (delete-window))
(kill-buffer buf)
- (org-agenda-maybe-reset-markers 'force))
+ (org-agenda-reset-markers)
+ (org-columns-remove-overlays))
;; Maybe restore the pre-agenda window configuration.
(and org-agenda-restore-windows-after-quit
(not (eq org-agenda-window-setup 'other-frame))
(setq org-agenda-new-buffers nil)
(org-agenda-quit))
+(defun org-agenda-execute (arg)
+ "Execute another agenda command, keeping same window.\\<global-map>
+So this is just a shortcut for `\\[org-agenda]', available in the agenda."
+ (interactive "P")
+ (let ((org-agenda-window-setup 'current-window))
+ (org-agenda arg)))
+
(defun org-save-all-org-buffers ()
"Save all Org-mode buffers without user confirmation."
(interactive)
(interactive)
(let* ((org-agenda-keep-modes t)
(line (org-current-line))
- (window-line (- line (org-current-line (window-start)))))
+ (window-line (- line (org-current-line (window-start))))
+ (lprops (get 'org-agenda-redo-command 'org-lprops)))
(message "Rebuilding agenda buffer...")
- (eval org-agenda-redo-command)
+ (org-let lprops '(eval org-agenda-redo-command))
(setq org-agenda-undo-list nil
org-agenda-pending-undo-list nil)
(message "Rebuilding agenda buffer...done")
(goto-line line)
(recenter window-line)))
+(defun org-agenda-manipulate-query-add ()
+ "Manipulate the query by adding a search term with positive selection.
+Positive selection means, the term must be matched for selection of an entry."
+ (interactive)
+ (org-agenda-manipulate-query ?\[))
+(defun org-agenda-manipulate-query-subtract ()
+ "Manipulate the query by adding a search term with negative selection.
+Negative selection means, term must not be matched for selection of an entry."
+ (interactive)
+ (org-agenda-manipulate-query ?\]))
+(defun org-agenda-manipulate-query-add-re ()
+ "Manipulate the query by adding a search regexp with positive selection.
+Positive selection means, the regexp must match for selection of an entry."
+ (interactive)
+ (org-agenda-manipulate-query ?\{))
+(defun org-agenda-manipulate-query-subtract-re ()
+ "Manipulate the query by adding a search regexp with negative selection.
+Negative selection means, regexp must not match for selection of an entry."
+ (interactive)
+ (org-agenda-manipulate-query ?\}))
+(defun org-agenda-manipulate-query (char)
+ (cond
+ ((eq org-agenda-type 'search)
+ (org-add-to-string
+ 'org-agenda-query-string
+ (cdr (assoc char '((?\[ . " +") (?\] . " -")
+ (?\{ . " +{}") (?\} . " -{}")))))
+ (setq org-agenda-redo-command
+ (list 'org-search-view
+ (+ (length org-agenda-query-string)
+ (if (member char '(?\{ ?\})) 0 1))
+ org-agenda-query-string))
+ (set-register org-agenda-query-register org-agenda-query-string)
+ (org-agenda-redo))
+ (t (error "Canot manipulate query for %s-type agenda buffers"
+ org-agenda-type))))
+
+(defun org-add-to-string (var string)
+ (set var (concat (symbol-value var) string)))
+
+(defun org-agenda-goto-date (date)
+ "Jump to DATE in agenda."
+ (interactive (list (org-read-date)))
+ (org-agenda-list nil date))
+
(defun org-agenda-goto-today ()
"Go to today."
(interactive)
(cond
(tdpos (goto-char tdpos))
((eq org-agenda-type 'agenda)
- (let ((org-agenda-overriding-arguments org-agenda-last-arguments))
- (setf (nth 1 org-agenda-overriding-arguments) nil)
+ (let* ((sd (time-to-days
+ (time-subtract (current-time)
+ (list 0 (* 3600 org-extend-today-until) 0))))
+ (comp (org-agenda-compute-time-span sd org-agenda-span))
+ (org-agenda-overriding-arguments org-agenda-last-arguments))
+ (setf (nth 1 org-agenda-overriding-arguments) (car comp))
+ (setf (nth 2 org-agenda-overriding-arguments) (cdr comp))
(org-agenda-redo)
- (org-agenda-find-today-or-agenda)))
+ (org-agenda-find-same-or-today-or-agenda)))
(t (error "Cannot find today")))))
-(defun org-agenda-find-today-or-agenda ()
+(defun org-agenda-find-same-or-today-or-agenda (&optional cnt)
(goto-char
- (or (text-property-any (point-min) (point-max) 'org-today t)
+ (or (and cnt (text-property-any (point-min) (point-max) 'org-day-cnt cnt))
+ (text-property-any (point-min) (point-max) 'org-today t)
(text-property-any (point-min) (point-max) 'org-agenda-type 'agenda)
(point-min))))
(defun org-agenda-later (arg)
- "Go forward in time by `org-agenda-ndays' days.
-With prefix ARG, go forward that many times `org-agenda-ndays'."
+ "Go forward in time by thee current span.
+With prefix ARG, go forward that many times the current span."
(interactive "p")
(org-agenda-check-type t 'agenda)
- (let ((org-agenda-overriding-arguments
- (list (car org-agenda-last-arguments)
- (+ org-starting-day (* arg org-agenda-ndays))
- nil t)))
- (org-agenda-redo)
- (org-agenda-find-today-or-agenda)))
+ (let* ((span org-agenda-span)
+ (sd org-starting-day)
+ (greg (calendar-gregorian-from-absolute sd))
+ (cnt (get-text-property (point) 'org-day-cnt))
+ greg2 nd)
+ (cond
+ ((eq span 'day)
+ (setq sd (+ arg sd) nd 1))
+ ((eq span 'week)
+ (setq sd (+ (* 7 arg) sd) nd 7))
+ ((eq span 'month)
+ (setq greg2 (list (+ (car greg) arg) (nth 1 greg) (nth 2 greg))
+ sd (calendar-absolute-from-gregorian greg2))
+ (setcar greg2 (1+ (car greg2)))
+ (setq nd (- (calendar-absolute-from-gregorian greg2) sd)))
+ ((eq span 'year)
+ (setq greg2 (list (car greg) (nth 1 greg) (+ arg (nth 2 greg)))
+ sd (calendar-absolute-from-gregorian greg2))
+ (setcar (nthcdr 2 greg2) (1+ (nth 2 greg2)))
+ (setq nd (- (calendar-absolute-from-gregorian greg2) sd))))
+ (let ((org-agenda-overriding-arguments
+ (list (car org-agenda-last-arguments) sd nd t)))
+ (org-agenda-redo)
+ (org-agenda-find-same-or-today-or-agenda cnt))))
(defun org-agenda-earlier (arg)
- "Go back in time by `org-agenda-ndays' days.
-With prefix ARG, go back that many times `org-agenda-ndays'."
+ "Go backward in time by the current span.
+With prefix ARG, go backward that many times the current span."
(interactive "p")
- (org-agenda-check-type t 'agenda)
- (let ((org-agenda-overriding-arguments
- (list (car org-agenda-last-arguments)
- (- org-starting-day (* arg org-agenda-ndays))
- nil t)))
- (org-agenda-redo)
- (org-agenda-find-today-or-agenda)))
+ (org-agenda-later (- arg)))
+(defun org-agenda-day-view ()
+ "Switch to daily view for agenda."
+ (interactive)
+ (setq org-agenda-ndays 1)
+ (org-agenda-change-time-span 'day))
(defun org-agenda-week-view ()
- "Switch to weekly view for agenda."
+ "Switch to daily view for agenda."
(interactive)
- (org-agenda-check-type t 'agenda)
- (if (= org-agenda-ndays 7)
- (error "This is already the week view"))
(setq org-agenda-ndays 7)
- (let ((org-agenda-overriding-arguments
- (list (car org-agenda-last-arguments)
- (or (get-text-property (point) 'day)
- org-starting-day)
- nil t)))
- (org-agenda-redo)
- (org-agenda-find-today-or-agenda))
- (org-agenda-set-mode-name)
- (message "Switched to week view"))
-
-(defun org-agenda-day-view ()
+ (org-agenda-change-time-span 'week))
+(defun org-agenda-month-view ()
+ "Switch to daily view for agenda."
+ (interactive)
+ (org-agenda-change-time-span 'month))
+(defun org-agenda-year-view ()
"Switch to daily view for agenda."
(interactive)
+ (if (y-or-n-p "Are you sure you want to compute the agenda for an entire year? ")
+ (org-agenda-change-time-span 'year)
+ (error "Abort")))
+
+(defun org-agenda-change-time-span (span)
+ "Change the agenda view to SPAN.
+SPAN may be `day', `week', `month', `year'."
(org-agenda-check-type t 'agenda)
- (if (= org-agenda-ndays 1)
- (error "This is already the day view"))
- (setq org-agenda-ndays 1)
- (let ((org-agenda-overriding-arguments
- (list (car org-agenda-last-arguments)
- (or (get-text-property (point) 'day)
- org-starting-day)
- nil t)))
+ (if (equal org-agenda-span span)
+ (error "Viewing span is already \"%s\"" span))
+ (let* ((sd (or (get-text-property (point) 'day)
+ org-starting-day))
+ (computed (org-agenda-compute-time-span sd span))
+ (org-agenda-overriding-arguments
+ (list (car org-agenda-last-arguments)
+ (car computed) (cdr computed) t)))
(org-agenda-redo)
- (org-agenda-find-today-or-agenda))
+ (org-agenda-find-same-or-today-or-agenda))
(org-agenda-set-mode-name)
- (message "Switched to day view"))
-
-;; FIXME: this no longer works if user make date format that starts with a blank
+ (message "Switched to %s view" span))
+
+(defun org-agenda-compute-time-span (sd span)
+ "Compute starting date and number of days for agenda.
+SPAN may be `day', `week', `month', `year'. The return value
+is a cons cell with the starting date and the number of days,
+so that the date SD will be in that range."
+ (let* ((greg (calendar-gregorian-from-absolute sd))
+ nd)
+ (cond
+ ((eq span 'day)
+ (setq nd 1))
+ ((eq span 'week)
+ (let* ((nt (calendar-day-of-week
+ (calendar-gregorian-from-absolute sd)))
+ (d (if org-agenda-start-on-weekday
+ (- nt org-agenda-start-on-weekday)
+ 0)))
+ (setq sd (- sd (+ (if (< d 0) 7 0) d)))
+ (setq nd 7)))
+ ((eq span 'month)
+ (setq sd (calendar-absolute-from-gregorian
+ (list (car greg) 1 (nth 2 greg)))
+ nd (- (calendar-absolute-from-gregorian
+ (list (1+ (car greg)) 1 (nth 2 greg)))
+ sd)))
+ ((eq span 'year)
+ (setq sd (calendar-absolute-from-gregorian
+ (list 1 1 (nth 2 greg)))
+ nd (- (calendar-absolute-from-gregorian
+ (list 1 1 (1+ (nth 2 greg))))
+ sd))))
+ (cons sd nd)))
+
+;; FIXME: does not work if user makes date format that starts with a blank
(defun org-agenda-next-date-line (&optional arg)
"Jump to the next line indicating a date in agenda buffer."
(interactive "p")
"Detach overlay INDEX."
(funcall (if (featurep 'xemacs) 'detach-extent 'delete-overlay) org-hl))
+;; FIXME this is currently not used.
(defun org-highlight-until-next-command (beg end &optional buffer)
(org-highlight beg end buffer)
(add-hook 'pre-command-hook 'org-unhighlight-once))
-
(defun org-unhighlight-once ()
(remove-hook 'pre-command-hook 'org-unhighlight-once)
(org-unhighlight))
(save-excursion
(and (outline-next-heading)
(org-flag-heading nil)))) ; show the next heading
+ (recenter (/ (window-height) 2))
+ (run-hooks 'org-agenda-after-show-hook)
(and highlight (org-highlight (point-at-bol) (point-at-eol)))))
+(defvar org-agenda-after-show-hook nil
+ "Normal hook run after an item has been shown from the agenda.
+Point is in the buffer where the item originated.")
+
(defun org-agenda-kill ()
"Kill the entry or subtree belonging to the current agenda entry."
(interactive)
(org-agenda-error)))
(buffer (marker-buffer marker))
(pos (marker-position marker))
+ (type (get-text-property (point) 'type))
dbeg dend (n 0) conf)
(org-with-remote-undo buffer
(with-current-buffer buffer
(save-excursion
(goto-char pos)
- (if (org-mode-p)
+ (if (and (org-mode-p) (not (member type '("sexp"))))
(setq dbeg (progn (org-back-to-heading t) (point))
- dend (org-end-of-subtree t))
+ dend (org-end-of-subtree t t))
(setq dbeg (point-at-bol)
dend (min (point-max) (1+ (point-at-eol)))))
(goto-char dbeg)
(setq p (marker-position m))
(>= p beg)
(<= p end))
- (let (buffer-read-only)
+ (let ((inhibit-read-only t))
(delete-region (point-at-bol) (1+ (point-at-eol)))))
(beginning-of-line 0))))))
(defun org-agenda-open-link ()
"Follow the link in the current line, if any."
(interactive)
- (let ((eol (point-at-eol)))
- (save-excursion
- (if (or (re-search-forward org-bracket-link-regexp eol t)
- (re-search-forward org-angle-link-re eol t)
- (re-search-forward org-plain-link-re eol t))
- (call-interactively 'org-open-at-point)
- (error "No link in current line")))))
+ (org-agenda-copy-local-variable 'org-link-abbrev-alist-local)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region (point-at-bol) (point-at-eol))
+ (org-open-at-point))))
+
+(defun org-agenda-copy-local-variable (var)
+ "Get a variable from a referenced buffer and install it here."
+ (let ((m (get-text-property (point) 'org-marker)))
+ (when (and m (buffer-live-p (marker-buffer m)))
+ (org-set-local var (with-current-buffer (marker-buffer m)
+ (symbol-value var))))))
(defun org-agenda-switch-to (&optional delete-other-windows)
"Go to the Org-mode file which contains the item at point."
"Marker pointing to the headline that last changed its TODO state
by a remote command from the agenda.")
+(defun org-agenda-todo-nextset ()
+ "Switch TODO entry to next sequence."
+ (interactive)
+ (org-agenda-todo 'nextset))
+
+(defun org-agenda-todo-previousset ()
+ "Switch TODO entry to previous sequence."
+ (interactive)
+ (org-agenda-todo 'previousset))
+
(defun org-agenda-todo (&optional arg)
"Cycle TODO state of line at point, also in Org-mode file.
This changes the line at point, all other lines in the agenda referring to
(buffer (marker-buffer marker))
(pos (marker-position marker))
(hdmarker (get-text-property (point) 'org-hd-marker))
- (buffer-read-only nil)
+ (inhibit-read-only t)
newhead)
(org-with-remote-undo buffer
(with-current-buffer buffer
`equal' against all `org-hd-marker' text properties in the file.
If FIXFACE is non-nil, the face of each item is modified acording to
the new TODO state."
- (let* ((buffer-read-only nil)
+ (let* ((inhibit-read-only t)
props m pl undone-face done-face finish new dotime cat tags)
(save-excursion
(goto-char (point-max))
(beginning-of-line 0)))
(org-finalize-agenda)))
-;; FIXME: allow negative value for org-agenda-align-tags-to-column
-;; See the code in set-tags for the way to do this.
(defun org-agenda-align-tags (&optional line)
- "Align all tags in agenda items to `org-agenda-align-tags-to-column'."
- (let ((buffer-read-only))
+ "Align all tags in agenda items to `org-agenda-tags-column'."
+ (let ((inhibit-read-only t) l c)
(save-excursion
(goto-char (if line (point-at-bol) (point-min)))
- (while (re-search-forward "\\([ \t]+\\):[a-zA-Z0-9_@:]+:[ \t]*$"
+ (while (re-search-forward (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@:]+:\\)[ \t]*$")
(if line (point-at-eol) nil) t)
+ (add-text-properties
+ (match-beginning 2) (match-end 2)
+ (list 'face (delq nil (list 'org-tag (get-text-property
+ (match-beginning 2) 'face)))))
+ (setq l (- (match-end 2) (match-beginning 2))
+ c (if (< org-agenda-tags-column 0)
+ (- (abs org-agenda-tags-column) l)
+ org-agenda-tags-column))
(delete-region (match-beginning 1) (match-end 1))
(goto-char (match-beginning 1))
(insert (org-add-props
- (make-string (max 1 (- org-agenda-align-tags-to-column
- (current-column))) ?\ )
+ (make-string (max 1 (- c (current-column))) ?\ )
(text-properties-at (point))))))))
(defun org-agenda-priority-up ()
(org-agenda-check-no-diary)
(let* ((marker (or (get-text-property (point) 'org-marker)
(org-agenda-error)))
- (buffer (marker-buffer marker))
- (pos (marker-position marker))
(hdmarker (get-text-property (point) 'org-hd-marker))
- (buffer-read-only nil)
+ (buffer (marker-buffer hdmarker))
+ (pos (marker-position hdmarker))
+ (inhibit-read-only t)
newhead)
(org-with-remote-undo buffer
(with-current-buffer buffer
the targets in the same sequence as the headlines appear, i.e.
the tags of the current headline come last."
(interactive)
- (let (tags)
+ (let (tags lastpos)
(save-excursion
(save-restriction
(widen)
(goto-char (or pos (point)))
(save-match-data
- (org-back-to-heading t)
(condition-case nil
- (while t
- (if (looking-at "[^\r\n]+?:\\([a-zA-Z_@0-9:]+\\):[ \t]*\\([\n\r]\\|\\'\\)")
- (setq tags (append (org-split-string
- (org-match-string-no-properties 1) ":")
- tags)))
- (or org-use-tag-inheritance (error ""))
- (org-up-heading-all 1))
+ (progn
+ (org-back-to-heading t)
+ (while (not (equal lastpos (point)))
+ (setq lastpos (point))
+ (if (looking-at (org-re "[^\r\n]+?:\\([[:alnum:]_@:]+\\):[ \t]*$"))
+ (setq tags (append (org-split-string
+ (org-match-string-no-properties 1) ":")
+ tags)))
+ (or org-use-tag-inheritance (error ""))
+ (org-up-heading-all 1)))
(error nil))))
tags)))
"Set tags for the current headline."
(interactive)
(org-agenda-check-no-diary)
- (org-agenda-show) ;;; FIXME This is a stupid hack and should not be needed
- (let* ((hdmarker (or (get-text-property (point) 'org-hd-marker)
- (org-agenda-error)))
- (buffer (marker-buffer hdmarker))
- (pos (marker-position hdmarker))
- (buffer-read-only nil)
- newhead)
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (org-show-context 'agenda)
- (save-excursion
- (and (outline-next-heading)
- (org-flag-heading nil))) ; show the next heading
- (call-interactively 'org-set-tags)
- (end-of-line 1)
- (setq newhead (org-get-heading)))
- (org-agenda-change-all-lines newhead hdmarker)
- (beginning-of-line 1))))
+ (if (and (org-region-active-p) (interactive-p))
+ (call-interactively 'org-change-tag-in-region)
+ (org-agenda-show) ;;; FIXME This is a stupid hack and should not be needed
+ (let* ((hdmarker (or (get-text-property (point) 'org-hd-marker)
+ (org-agenda-error)))
+ (buffer (marker-buffer hdmarker))
+ (pos (marker-position hdmarker))
+ (inhibit-read-only t)
+ newhead)
+ (org-with-remote-undo buffer
+ (with-current-buffer buffer
+ (widen)
+ (goto-char pos)
+ (save-excursion
+ (org-show-context 'agenda))
+ (save-excursion
+ (and (outline-next-heading)
+ (org-flag-heading nil))) ; show the next heading
+ (goto-char pos)
+ (call-interactively 'org-set-tags)
+ (end-of-line 1)
+ (setq newhead (org-get-heading)))
+ (org-agenda-change-all-lines newhead hdmarker)
+ (beginning-of-line 1)))))
(defun org-agenda-toggle-archive-tag ()
"Toggle the archive tag for the current entry."
(org-agenda-error)))
(buffer (marker-buffer hdmarker))
(pos (marker-position hdmarker))
- (buffer-read-only nil)
+ (inhibit-read-only t)
newhead)
(org-with-remote-undo buffer
(with-current-buffer buffer
(interactive "p")
(org-agenda-date-later (- arg) what))
-(defun org-agenda-show-new-time (marker stamp)
+(defun org-agenda-show-new-time (marker stamp &optional prefix)
"Show new date stamp via text properties."
;; We use text properties to make this undoable
- (let ((buffer-read-only nil))
- (setq stamp (concat " => " stamp))
+ (let ((inhibit-read-only t))
+ (setq stamp (concat " " prefix " => " stamp))
(save-excursion
(goto-char (point-max))
(while (not (bobp))
(org-agenda-check-no-diary)
(let* ((marker (or (get-text-property (point) 'org-marker)
(org-agenda-error)))
+ (type (marker-insertion-type marker))
(buffer (marker-buffer marker))
(pos (marker-position marker))
(org-insert-labeled-timestamps-at-point nil)
ts)
+ (when type (message "%s" type) (sit-for 3))
+ (set-marker-insertion-type marker t)
(org-with-remote-undo buffer
(with-current-buffer buffer
(widen)
(goto-char pos)
- (setq ts (org-schedule))
- (message "Item scheduled for %s" ts)))))
+ (setq ts (org-schedule arg)))
+ (org-agenda-show-new-time marker ts "S"))
+ (message "Item scheduled for %s" ts)))
(defun org-agenda-deadline (arg)
"Schedule the item at point."
(with-current-buffer buffer
(widen)
(goto-char pos)
- (setq ts (org-deadline))
- (message "Deadline for this item set to %s" ts)))))
+ (setq ts (org-deadline arg)))
+ (org-agenda-show-new-time marker ts "S"))
+ (message "Deadline for this item set to %s" ts)))
-(defun org-get-heading ()
+(defun org-get-heading (&optional no-tags)
"Return the heading of the current entry, without the stars."
(save-excursion
(org-back-to-heading t)
- (if (looking-at "\\*+[ \t]+\\([^\r\n]*\\)") (match-string 1) "")))
+ (if (looking-at
+ (if no-tags
+ (org-re "\\*+[ \t]+\\([^\n\r]*?\\)\\([ \t]+:[[:alnum:]:_@]+:[ \t]*\\)?$")
+ "\\*+[ \t]+\\([^\r\n]*\\)"))
+ (match-string 1) "")))
(defun org-agenda-clock-in (&optional arg)
"Start the clock on the currently selected item."
(point (point))
(date (calendar-gregorian-from-absolute
(get-text-property point 'day)))
- ;; the following 3 vars are needed in the calendar
- (displayed-day (extract-calendar-day date))
- (displayed-month (extract-calendar-month date))
- (displayed-year (extract-calendar-year date)))
+ ;; the following 2 vars are needed in the calendar
+ (displayed-month (car date))
+ (displayed-year (nth 2 date)))
(unwind-protect
(progn
(fset 'calendar-cursor-to-date
(interactive)
(org-agenda-execute-calendar-command 'list-calendar-holidays))
+(defvar calendar-longitude)
+(defvar calendar-latitude)
+(defvar calendar-location-name)
+
(defun org-agenda-sunrise-sunset (arg)
"Display sunrise and sunset for the cursor date.
Latitude and longitude can be specified with the variables
`calendar-latitude' and `calendar-longitude'. When called with prefix
argument, latitude and longitude will be prompted for."
(interactive "P")
+ (require 'solar)
(let ((calendar-longitude (if arg nil calendar-longitude))
(calendar-latitude (if arg nil calendar-latitude))
(calendar-location-name
(error "Don't know which date to open in calendar")))
(date (calendar-gregorian-from-absolute day))
(calendar-move-hook nil)
+ (calendar-view-holidays-initially-flag nil)
(view-calendar-holidays-initially nil)
+ (calendar-view-diary-initially-flag nil)
(view-diary-entries-initially nil))
(calendar)
(calendar-goto-date date)))
"Hebrew: " (calendar-hebrew-date-string date) " (until sunset)\n"
"Islamic: " (calendar-islamic-date-string date) " (until sunset)\n"
"French: " (calendar-french-date-string date) "\n"
+ "Baha'i: " (calendar-bahai-date-string date) " (until sunset)\n"
"Mayan: " (calendar-mayan-date-string date) "\n"
"Coptic: " (calendar-coptic-date-string date) "\n"
"Ethiopic: " (calendar-ethiopic-date-string date) "\n"
(defvar org-cdlatex-mode-map (make-sparse-keymap)
"Keymap for the minor `org-cdlatex-mode'.")
-(define-key org-cdlatex-mode-map "_" 'org-cdlatex-underscore-caret)
-(define-key org-cdlatex-mode-map "^" 'org-cdlatex-underscore-caret)
-(define-key org-cdlatex-mode-map "`" 'cdlatex-math-symbol)
-(define-key org-cdlatex-mode-map "'" 'org-cdlatex-math-modify)
-(define-key org-cdlatex-mode-map "\C-c{" 'cdlatex-environment)
+(org-defkey org-cdlatex-mode-map "_" 'org-cdlatex-underscore-caret)
+(org-defkey org-cdlatex-mode-map "^" 'org-cdlatex-underscore-caret)
+(org-defkey org-cdlatex-mode-map "`" 'cdlatex-math-symbol)
+(org-defkey org-cdlatex-mode-map "'" 'org-cdlatex-math-modify)
+(org-defkey org-cdlatex-mode-map "\C-c{" 'cdlatex-environment)
(defvar org-cdlatex-texmathp-advice-is-done nil
"Flag remembering if we have applied the advice to texmathp already.")
(while (string-match re str start)
(cond
((= (match-end 0) (length str))
- (throw 'exit (cons "$" (+ lim (match-beginning 0)))))
+ (throw 'exit (cons "$" (+ lim (match-beginning 0) 1))))
((= (match-end 0) (- (length str) 5))
(throw 'exit nil))
(t (setq start (match-end 0))))))
"Creating images for entry...%s"))))
(message msg "")
(narrow-to-region beg end)
+ (goto-char beg)
(org-format-latex
(concat "ltxpng/" (file-name-sans-extension
(file-name-nondirectory
buffer-file-name)))
- default-directory 'overlays msg at)
+ default-directory 'overlays msg at 'forbuffer)
(message msg "done. Use `C-c C-c' to remove images.")))))
(defvar org-latex-regexps
("$$" "\\$\\$[^\000]*?\\$\\$" 0 t))
"Regular expressions for matching embedded LaTeX.")
-(defun org-format-latex (prefix &optional dir overlays msg at)
+(defun org-format-latex (prefix &optional dir overlays msg at forbuffer)
"Replace LaTeX fragments with links to an image, and produce images."
(if (and overlays (fboundp 'clear-image-cache)) (clear-image-cache))
(let* ((prefixnodir (file-name-nondirectory prefix))
(setq checkdir t)
(or (file-directory-p todir) (make-directory todir)))
(org-create-formula-image
- txt movefile opt)
+ txt movefile opt forbuffer)
(if overlays
(progn
(setq ov (org-make-overlay beg end))
(insert link))))))))
;; This function borrows from Ganesh Swami's latex2png.el
-(defun org-create-formula-image (string tofile options)
+(defun org-create-formula-image (string tofile options buffer)
(let* ((tmpdir (if (featurep 'xemacs)
(temp-directory)
temporary-file-directory))
(texfilebase (make-temp-name
(expand-file-name "orgtex" tmpdir)))
-
-;(texfilebase (make-temp-file "orgtex"))
-; (dummy (delete-file texfilebase))
(texfile (concat texfilebase ".tex"))
(dvifile (concat texfilebase ".dvi"))
(pngfile (concat texfilebase ".png"))
- (scale (number-to-string (* 1000 (or (plist-get options :scale) 1.0))))
- (fg (or (plist-get options :foreground) "Black"))
- (bg (or (plist-get options :background) "Transparent")))
+ (fnh (face-attribute 'default :height nil))
+ (scale (or (plist-get options (if buffer :scale :html-scale)) 1.0))
+ (dpi (number-to-string (* scale (floor (* 0.9 (if buffer fnh 140.))))))
+ (fg (or (plist-get options (if buffer :foreground :html-foreground))
+ "Black"))
+ (bg (or (plist-get options (if buffer :background :html-background))
+ "Transparent")))
+ (if (eq fg 'default) (setq fg (org-dvipng-color :foreground)))
+ (if (eq bg 'default) (setq bg (org-dvipng-color :background)))
(with-temp-file texfile
- (insert "\\documentclass{article}
-\\usepackage{fullpage}
-\\usepackage{amssymb}
-\\usepackage[usenames]{color}
-\\usepackage{amsmath}
-\\usepackage{latexsym}
-\\usepackage[mathscr]{eucal}
-\\pagestyle{empty}
-\\begin{document}\n" string "\n\\end{document}\n"))
+ (insert org-format-latex-header
+ "\n\\begin{document}\n" string "\n\\end{document}\n"))
(let ((dir default-directory))
(condition-case nil
(progn
(progn (message "Failed to create dvi file from %s" texfile) nil)
(call-process "dvipng" nil nil nil
"-E" "-fg" fg "-bg" bg
- "-x" scale "-y" scale "-T" "tight"
+ "-D" dpi
+ ;;"-x" scale "-y" scale
+ "-T" "tight"
"-o" pngfile
dvifile)
(if (not (file-exists-p pngfile))
(delete-file (concat texfilebase e)))
pngfile))))
+(defun org-dvipng-color (attr)
+ "Return an rgb color specification for dvipng."
+ (apply 'format "rgb %s %s %s"
+ (mapcar 'org-normalize-color
+ (color-values (face-attribute 'default attr nil)))))
+
+(defun org-normalize-color (value)
+ "Return string to be used as color value for an RGB component."
+ (format "%g" (/ value 65535.0)))
+
;;;; Exporting
;;; Variables, constants, and parameter plists
(:headline-levels . org-export-headline-levels)
(:section-numbers . org-export-with-section-numbers)
(:table-of-contents . org-export-with-toc)
+ (:preserve-breaks . org-export-preserve-breaks)
(:archived-trees . org-export-with-archived-trees)
(:emphasize . org-export-with-emphasize)
(:sub-superscript . org-export-with-sub-superscripts)
+ (:special-strings . org-export-with-special-strings)
+ (:footnotes . org-export-with-footnotes)
+ (:drawers . org-export-with-drawers)
+ (:tags . org-export-with-tags)
(:TeX-macros . org-export-with-TeX-macros)
(:LaTeX-fragments . org-export-with-LaTeX-fragments)
+ (:skip-before-1st-heading . org-export-skip-text-before-1st-heading)
(:fixed-width . org-export-with-fixed-width)
(:timestamps . org-export-with-timestamps)
+ (:author-info . org-export-author-info)
+ (:time-stamp-file . org-export-time-stamp-file)
(:tables . org-export-with-tables)
(:table-auto-headline . org-export-highlight-first-table-line)
(:style . org-export-html-style)
+ (:agenda-style . org-agenda-export-html-style)
(:convert-org-links . org-export-html-link-org-files-as-html)
(:inline-images . org-export-html-inline-images)
+ (:html-extension . org-export-html-extension)
+ (:html-table-tag . org-export-html-table-tag)
(:expand-quoted-html . org-export-html-expand)
(:timestamp . org-export-html-with-timestamp)
(:publishing-directory . org-export-publishing-directory)
(defun org-infile-export-plist ()
"Return the property list with file-local settings for export."
(save-excursion
- (goto-char 0)
- (let ((re (org-make-options-regexp
- '("TITLE" "AUTHOR" "EMAIL" "TEXT" "OPTIONS" "LANGUAGE")))
- p key val text options)
- (while (re-search-forward re nil t)
- (setq key (org-match-string-no-properties 1)
- val (org-match-string-no-properties 2))
- (cond
- ((string-equal key "TITLE") (setq p (plist-put p :title val)))
- ((string-equal key "AUTHOR")(setq p (plist-put p :author val)))
- ((string-equal key "EMAIL") (setq p (plist-put p :email val)))
- ((string-equal key "LANGUAGE") (setq p (plist-put p :language val)))
- ((string-equal key "TEXT")
- (setq text (if text (concat text "\n" val) val)))
- ((string-equal key "OPTIONS") (setq options val))))
- (setq p (plist-put p :text text))
- (when options
- (let ((op '(("H" . :headline-levels)
- ("num" . :section-numbers)
- ("toc" . :table-of-contents)
- ("\\n" . :preserve-breaks)
- ("@" . :expand-quoted-html)
- (":" . :fixed-width)
- ("|" . :tables)
- ("^" . :sub-superscript)
- ("*" . :emphasize)
- ("TeX" . :TeX-macros)
- ("LaTeX" . :LaTeX-fragments)))
- o)
- (while (setq o (pop op))
- (if (string-match (concat (regexp-quote (car o))
- ":\\([^ \t\n\r;,.]*\\)")
- options)
- (setq p (plist-put p (cdr o)
- (car (read-from-string
- (match-string 1 options)))))))))
- p)))
+ (save-restriction
+ (widen)
+ (goto-char 0)
+ (let ((re (org-make-options-regexp
+ '("TITLE" "AUTHOR" "DATE" "EMAIL" "TEXT" "OPTIONS" "LANGUAGE")))
+ p key val text options)
+ (while (re-search-forward re nil t)
+ (setq key (org-match-string-no-properties 1)
+ val (org-match-string-no-properties 2))
+ (cond
+ ((string-equal key "TITLE") (setq p (plist-put p :title val)))
+ ((string-equal key "AUTHOR")(setq p (plist-put p :author val)))
+ ((string-equal key "EMAIL") (setq p (plist-put p :email val)))
+ ((string-equal key "DATE") (setq p (plist-put p :date val)))
+ ((string-equal key "LANGUAGE") (setq p (plist-put p :language val)))
+ ((string-equal key "TEXT")
+ (setq text (if text (concat text "\n" val) val)))
+ ((string-equal key "OPTIONS") (setq options val))))
+ (setq p (plist-put p :text text))
+ (when options
+ (let ((op '(("H" . :headline-levels)
+ ("num" . :section-numbers)
+ ("toc" . :table-of-contents)
+ ("\\n" . :preserve-breaks)
+ ("@" . :expand-quoted-html)
+ (":" . :fixed-width)
+ ("|" . :tables)
+ ("^" . :sub-superscript)
+ ("-" . :special-strings)
+ ("f" . :footnotes)
+ ("d" . :drawers)
+ ("tags" . :tags)
+ ("*" . :emphasize)
+ ("TeX" . :TeX-macros)
+ ("LaTeX" . :LaTeX-fragments)
+ ("skip" . :skip-before-1st-heading)
+ ("author" . :author-info)
+ ("timestamp" . :time-stamp-file)))
+ o)
+ (while (setq o (pop op))
+ (if (string-match (concat (regexp-quote (car o))
+ ":\\([^ \t\n\r;,.]*\\)")
+ options)
+ (setq p (plist-put p (cdr o)
+ (car (read-from-string
+ (match-string 1 options)))))))))
+ p))))
(defun org-export-directory (type plist)
(let* ((val (plist-get plist :publishing-directory))
val)))
dir))
-(defun org-export-find-first-heading-line (list)
- "Remove all lines from LIST which are before the first headline."
- (let ((orig-list list)
- (re (concat "^" outline-regexp)))
- (while (and list
- (not (string-match re (car list))))
- (pop list))
- (or list orig-list)))
-
(defun org-skip-comments (lines)
"Skip lines starting with \"#\" and subtrees starting with COMMENT."
(let ((re1 (concat "^\\(\\*+\\)[ \t]+" org-comment-string))
(re2 "^\\(\\*+\\)[ \t\n\r]")
+ (case-fold-search nil)
rtn line level)
(while (setq line (pop lines))
(cond
\[v] limit export to visible part of outline tree
\[a] export as ASCII
+
\[h] export as HTML
+\[H] export as HTML to temporary buffer
+\[R] export region as HTML
\[b] export as HTML and browse immediately
\[x] export as XOXO
+\[l] export as LaTeX
+\[L] export as LaTeX to temporary buffer
+
\[i] export current file as iCalendar file
\[I] export all agenda files as iCalendar files
\[c] export agenda files into combined iCalendar file
(?a . org-export-as-ascii)
(?h . org-export-as-html)
(?b . org-export-as-html-and-open)
+ (?H . org-export-as-html-to-buffer)
+ (?R . org-export-region-as-html)
(?x . org-export-as-xoxo)
+ (?l . org-export-as-latex)
+ (?L . org-export-as-latex-to-buffer)
(?i . org-export-icalendar-this-file)
(?I . org-export-icalendar-all-agenda-files)
(?c . org-export-icalendar-combine-agenda-files)
("curren")
("yen")
("brvbar")
+ ("vert" . "|")
("sect")
("uml")
("copy")
("prop") ("proptp"."∝")
("infin") ("infty"."∞")
("ang") ("angle"."∠")
- ("and") ("vee"."∧")
- ("or") ("wedge"."∨")
+ ("and") ("wedge"."∧")
+ ("or") ("vee"."∨")
("cap")
("cup")
("int")
("clubs") ("clubsuit"."♣")
("hearts") ("diamondsuit"."♥")
("diams") ("diamondsuit"."♦")
+ ("smile"."☺") ("blacksmile"."☻") ("sad"."☹")
("quot")
("amp")
("lt")
;;; General functions for all backends
(defun org-cleaned-string-for-export (string &rest parameters)
- "Cleanup a buffer substring so that links can be created safely."
+ "Cleanup a buffer STRING so that links can be created safely."
(interactive)
(let* ((re-radio (and org-target-link-regexp
(concat "\\([^<]\\)\\(" org-target-link-regexp "\\)")))
(re-angle-link (concat "\\([^[]\\)" org-angle-link-re))
(re-archive (concat ":" org-archive-tag ":"))
(re-quote (concat "^\\*+[ \t]+" org-quote-string "\\>"))
- (htmlp (memq :for-html parameters))
- (outline-regexp "\\*+")
- rtn)
- (save-excursion
- (set-buffer (get-buffer-create " org-mode-tmp"))
+ (re-commented (concat "^\\*+[ \t]+" org-comment-string "\\>"))
+ (htmlp (plist-get parameters :for-html))
+ (asciip (plist-get parameters :for-ascii))
+ (latexp (plist-get parameters :for-LaTeX))
+ (commentsp (plist-get parameters :comments))
+ (archived-trees (plist-get parameters :archived-trees))
+ (inhibit-read-only t)
+ (drawers org-drawers)
+ (exp-drawers (plist-get parameters :drawers))
+ (outline-regexp "\\*+ ")
+ a b xx
+ rtn p)
+ (with-current-buffer (get-buffer-create " org-mode-tmp")
(erase-buffer)
(insert string)
+ ;; Remove license-to-kill stuff
+ (while (setq p (text-property-any (point-min) (point-max)
+ :org-license-to-kill t))
+ (delete-region p (next-single-property-change p :org-license-to-kill)))
+
(let ((org-inhibit-startup t)) (org-mode))
(untabify (point-min) (point-max))
+ ;; Get rid of drawers
+ (unless (eq t exp-drawers)
+ (goto-char (point-min))
+ (let ((re (concat "^[ \t]*:\\("
+ (mapconcat
+ 'identity
+ (org-delete-all exp-drawers
+ (copy-sequence drawers))
+ "\\|")
+ "\\):[ \t]*\n\\([^@]*?\n\\)?[ \t]*:END:[ \t]*\n")))
+ (while (re-search-forward re nil t)
+ (replace-match ""))))
+
+ ;; Get the correct stuff before the first headline
+ (when (plist-get parameters :skip-before-1st-heading)
+ (goto-char (point-min))
+ (when (re-search-forward "^\\*+[ \t]" nil t)
+ (delete-region (point-min) (match-beginning 0))
+ (goto-char (point-min))
+ (insert "\n")))
+ (when (plist-get parameters :add-text)
+ (goto-char (point-min))
+ (insert (plist-get parameters :add-text) "\n"))
+
;; Get rid of archived trees
- (when (not (eq org-export-with-archived-trees t))
+ (when (not (eq archived-trees t))
(goto-char (point-min))
(while (re-search-forward re-archive nil t)
- (if (not (org-on-heading-p))
+ (if (not (org-on-heading-p t))
(org-end-of-subtree t)
(beginning-of-line 1)
- (delete-region
- (if org-export-with-archived-trees (1+ (point-at-eol)) (point))
- (org-end-of-subtree t)))))
+ (setq a (if archived-trees
+ (1+ (point-at-eol)) (point))
+ b (org-end-of-subtree t))
+ (if (> b a) (delete-region a b)))))
- ;; Protect stuff from HTML processing
+ ;; Find targets in comments and move them out of comments,
+ ;; but mark them as targets that should be invisible
(goto-char (point-min))
- (while (re-search-forward "^[ \t]*:.*\\(\n[ \t]*:.*\\)*" nil t)
- (add-text-properties (match-beginning 0) (match-end 0)
- '(org-protected t)))
- (when htmlp
+ (while (re-search-forward "^#.*?\\(<<<?[^>\r\n]+>>>?\\).*" nil t)
+ (replace-match "\\1(INVISIBLE)"))
+
+ ;; Protect backend specific stuff, throw away the others.
+ (let ((formatters
+ `((,htmlp "HTML" "BEGIN_HTML" "END_HTML")
+ (,asciip "ASCII" "BEGIN_ASCII" "END_ASCII")
+ (,latexp "LaTeX" "BEGIN_LaTeX" "END_LaTeX")))
+ fmt)
(goto-char (point-min))
- (while (re-search-forward "^#\\+HTML:[ \t]*\\(.*\\)" nil t)
- (replace-match "\\1" t)
- (add-text-properties
- (point-at-bol) (min (1+ (point-at-eol)) (point-max))
- '(org-protected t))))
- (goto-char (point-min))
- (while (re-search-forward
- "^#\\+BEGIN_HTML\\>.*\\(\n.*\\)*?\n#\\+END_HTML\\>.*\n?" nil t)
- (if htmlp
- (add-text-properties (match-beginning 1) (1+ (match-end 1))
- '(org-protected t))
- (delete-region (match-beginning 0) (match-end 0))))
+ (while (re-search-forward "^#\\+BEGIN_EXAMPLE[ \t]*\n" nil t)
+ (goto-char (match-end 0))
+ (while (not (looking-at "#\\+END_EXAMPLE"))
+ (insert ": ")
+ (beginning-of-line 2)))
+ (goto-char (point-min))
+ (while (re-search-forward "^[ \t]*:.*\\(\n[ \t]*:.*\\)*" nil t)
+ (add-text-properties (match-beginning 0) (match-end 0)
+ '(org-protected t)))
+ (while formatters
+ (setq fmt (pop formatters))
+ (when (car fmt)
+ (goto-char (point-min))
+ (while (re-search-forward (concat "^#\\+" (cadr fmt)
+ ":[ \t]*\\(.*\\)") nil t)
+ (replace-match "\\1" t)
+ (add-text-properties
+ (point-at-bol) (min (1+ (point-at-eol)) (point-max))
+ '(org-protected t))))
+ (goto-char (point-min))
+ (while (re-search-forward
+ (concat "^#\\+"
+ (caddr fmt) "\\>.*\\(\\(\n.*\\)*?\n\\)#\\+"
+ (cadddr fmt) "\\>.*\n?") nil t)
+ (if (car fmt)
+ (add-text-properties (match-beginning 1) (1+ (match-end 1))
+ '(org-protected t))
+ (delete-region (match-beginning 0) (match-end 0))))))
+
+ ;; Protect quoted subtrees
(goto-char (point-min))
(while (re-search-forward re-quote nil t)
(goto-char (match-beginning 0))
(add-text-properties (point) (org-end-of-subtree t)
'(org-protected t)))
- ;; Find targets in comments and move them out of comments,
- ;; but mark them as targets that should be invisible
+ ;; Protect verbatim elements
(goto-char (point-min))
- (while (re-search-forward "^#.*?\\(<<<?[^>\r\n]+>>>?\\).*" nil t)
- (replace-match "\\1(INVISIBLE)"))
+ (while (re-search-forward org-verbatim-re nil t)
+ (add-text-properties (match-beginning 4) (match-end 4)
+ '(org-protected t))
+ (goto-char (1+ (match-end 4))))
- ;; Remove comments
+ ;; Remove subtrees that are commented
(goto-char (point-min))
- (while (re-search-forward "^#.*\n?" nil t)
- (replace-match ""))
+ (while (re-search-forward re-commented nil t)
+ (goto-char (match-beginning 0))
+ (delete-region (point) (org-end-of-subtree t)))
+
+ ;; Remove special table lines
+ (when org-export-table-remove-special-lines
+ (goto-char (point-min))
+ (while (re-search-forward "^[ \t]*|" nil t)
+ (beginning-of-line 1)
+ (if (or (looking-at "[ \t]*| *[!_^] *|")
+ (and (looking-at ".*?| *<[0-9]+> *|")
+ (not (looking-at ".*?| *[^ <|]"))))
+ (delete-region (max (point-min) (1- (point-at-bol)))
+ (point-at-eol))
+ (end-of-line 1))))
+
+ ;; Specific LaTeX stuff
+ (when latexp
+ (require 'org-export-latex nil)
+ (org-export-latex-cleaned-string))
+
+ (when asciip
+ (org-export-ascii-clean-string))
+
+ ;; Specific HTML stuff
+ (when htmlp
+ ;; Convert LaTeX fragments to images
+ (when (plist-get parameters :LaTeX-fragments)
+ (org-format-latex
+ (concat "ltxpng/" (file-name-sans-extension
+ (file-name-nondirectory
+ org-current-export-file)))
+ org-current-export-dir nil "Creating LaTeX image %s"))
+ (message "Exporting..."))
+
+ ;; Remove or replace comments
+ (goto-char (point-min))
+ (while (re-search-forward "^#\\(.*\n?\\)" nil t)
+ (if commentsp
+ (progn (add-text-properties
+ (match-beginning 0) (match-end 0) '(org-protected t))
+ (replace-match (format commentsp (match-string 1)) t t))
+ (replace-match "")))
;; Find matches for radio targets and turn them into internal links
(goto-char (point-min))
(replace-match "\\1 \\3")
(goto-char (match-beginning 0))))
- ;; Convert LaTeX fragments to images
- (when (memq :LaTeX-fragments parameters)
- (org-format-latex
- (concat "ltxpng/" (file-name-sans-extension
- (file-name-nondirectory
- org-current-export-file)))
- org-current-export-dir nil "Creating LaTeX image %s"))
- (message "Exporting...")
;; Normalize links: Convert angle and plain links into bracket links
;; Expand link abbreviations
(goto-char (point-min))
(while (re-search-forward re-plain-link nil t)
+ (goto-char (1- (match-end 0)))
(org-if-unprotected
- (replace-match
- (concat
- (match-string 1) "[[" (match-string 2) ":" (match-string 3) "]]")
- t t)))
+ (let* ((s (concat (match-string 1) "[[" (match-string 2)
+ ":" (match-string 3) "]]")))
+ ;; added 'org-link face to links
+ (put-text-property 0 (length s) 'face 'org-link s)
+ (replace-match s t t))))
(goto-char (point-min))
(while (re-search-forward re-angle-link nil t)
+ (goto-char (1- (match-end 0)))
(org-if-unprotected
- (replace-match
- (concat
- (match-string 1) "[[" (match-string 2) ":" (match-string 3) "]]")
- t t)))
+ (let* ((s (concat (match-string 1) "[[" (match-string 2)
+ ":" (match-string 3) "]]")))
+ (put-text-property 0 (length s) 'face 'org-link s)
+ (replace-match s t t))))
(goto-char (point-min))
(while (re-search-forward org-bracket-link-regexp nil t)
(org-if-unprotected
- (replace-match
- (concat "[[" (save-match-data
- (org-link-expand-abbrev (match-string 1)))
- "]"
- (if (match-end 3)
- (match-string 2)
- (concat "[" (match-string 1) "]"))
- "]")
- t t)))
+ (let* ((s (concat "[[" (setq xx (save-match-data
+ (org-link-expand-abbrev (match-string 1))))
+ "]"
+ (if (match-end 3)
+ (match-string 2)
+ (concat "[" xx "]"))
+ "]")))
+ (put-text-property 0 (length s) 'face 'org-link s)
+ (replace-match s t t))))
;; Find multiline emphasis and put them into single line
- (when (memq :emph-multiline parameters)
+ (when (plist-get parameters :emph-multiline)
(goto-char (point-min))
(while (re-search-forward org-emph-re nil t)
- (org-if-unprotected
- (subst-char-in-region (match-beginning 0) (match-end 0) ?\n ?\ t)
- (goto-char (1- (match-end 0))))))
+ (if (not (= (char-after (match-beginning 3))
+ (char-after (match-beginning 4))))
+ (org-if-unprotected
+ (subst-char-in-region (match-beginning 0) (match-end 0)
+ ?\n ?\ t)
+ (goto-char (1- (match-end 0))))
+ (goto-char (1+ (match-beginning 0))))))
(setq rtn (buffer-string)))
(kill-buffer " org-mode-tmp")
rtn))
+(defun org-export-grab-title-from-buffer ()
+ "Get a title for the current document, from looking at the buffer."
+ (let ((inhibit-read-only t))
+ (save-excursion
+ (goto-char (point-min))
+ (let ((end (save-excursion (outline-next-heading) (point))))
+ (when (re-search-forward "^[ \t]*[^|# \t\r\n].*\n" end t)
+ ;; Mark the line so that it will not be exported as normal text.
+ (org-unmodified
+ (add-text-properties (match-beginning 0) (match-end 0)
+ (list :org-license-to-kill t)))
+ ;; Return the title string
+ (org-trim (match-string 0)))))))
+
+(defun org-export-get-title-from-subtree ()
+ "Return subtree title and exclude it from export."
+ (let (title (m (mark)))
+ (save-excursion
+ (goto-char (region-beginning))
+ (when (and (org-at-heading-p)
+ (>= (org-end-of-subtree t t) (region-end)))
+ ;; This is a subtree, we take the title from the first heading
+ (goto-char (region-beginning))
+ (looking-at org-todo-line-regexp)
+ (setq title (match-string 3))
+ (org-unmodified
+ (add-text-properties (point) (1+ (point-at-eol))
+ (list :org-license-to-kill t)))))
+ title))
+
(defun org-solidify-link-text (s &optional alist)
"Take link text and make a safe target out of it."
(save-match-data
(a (assoc rtn alist)))
(or (cdr a) rtn))))
+(defun org-get-min-level (lines)
+ "Get the minimum level in LINES."
+ (let ((re "^\\(\\*+\\) ") l min)
+ (catch 'exit
+ (while (setq l (pop lines))
+ (if (string-match re l)
+ (throw 'exit (org-tr-level (length (match-string 1 l))))))
+ 1)))
+
;; Variable holding the vector with section numbers
(defvar org-section-numbers (make-vector org-level-max 0))
;;; ASCII export
(defvar org-last-level nil) ; dynamically scoped variable
+(defvar org-min-level nil) ; dynamically scoped variable
(defvar org-levels-open nil) ; dynamically scoped parameter
(defvar org-ascii-current-indentation nil) ; For communication
(setq-default org-todo-line-regexp org-todo-line-regexp)
(let* ((opt-plist (org-combine-plists (org-default-export-plist)
(org-infile-export-plist)))
- (region
- (buffer-substring
- (if (org-region-active-p) (region-beginning) (point-min))
- (if (org-region-active-p) (region-end) (point-max))))
+ (region-p (org-region-active-p))
+ (subtree-p
+ (when region-p
+ (save-excursion
+ (goto-char (region-beginning))
+ (and (org-at-heading-p)
+ (>= (org-end-of-subtree t t) (region-end))))))
(custom-times org-display-custom-times)
- (lines (org-export-find-first-heading-line
- (org-skip-comments
- (org-split-string
- (org-cleaned-string-for-export region)
- "[\r\n]"))))
(org-ascii-current-indentation '(0 . 0))
(level 0) line txt
(umax nil)
(filename (concat (file-name-as-directory
(org-export-directory :ascii opt-plist))
(file-name-sans-extension
- (file-name-nondirectory buffer-file-name))
+ (or (and subtree-p
+ (org-entry-get (region-beginning)
+ "EXPORT_FILE_NAME" t))
+ (file-name-nondirectory buffer-file-name)))
".txt"))
+ (filename (if (equal (file-truename filename)
+ (file-truename buffer-file-name))
+ (concat filename ".txt")
+ filename))
(buffer (find-file-noselect filename))
(org-levels-open (make-vector org-level-max nil))
(odd org-odd-levels-only)
- (date (format-time-string "%Y/%m/%d" (current-time)))
- (time (format-time-string "%X" (org-current-time)))
+ (date (plist-get opt-plist :date))
(author (plist-get opt-plist :author))
- (title (or (plist-get opt-plist :title)
+ (title (or (and subtree-p (org-export-get-title-from-subtree))
+ (plist-get opt-plist :title)
+ (and (not
+ (plist-get opt-plist :skip-before-1st-heading))
+ (org-export-grab-title-from-buffer))
(file-name-sans-extension
(file-name-nondirectory buffer-file-name))))
(email (plist-get opt-plist :email))
(language (plist-get opt-plist :language))
(quote-re0 (concat "^[ \t]*" org-quote-string "\\>"))
; (quote-re (concat "^\\(\\*+\\)\\([ \t]*" org-quote-string "\\>\\)"))
- (text nil)
(todo nil)
- (lang-words nil))
-
- (setq org-last-level 1)
+ (lang-words nil)
+ (region
+ (buffer-substring
+ (if (org-region-active-p) (region-beginning) (point-min))
+ (if (org-region-active-p) (region-end) (point-max))))
+ (lines (org-split-string
+ (org-cleaned-string-for-export
+ region
+ :for-ascii t
+ :skip-before-1st-heading
+ (plist-get opt-plist :skip-before-1st-heading)
+ :drawers (plist-get opt-plist :drawers)
+ :verbatim-multiline t
+ :archived-trees
+ (plist-get opt-plist :archived-trees)
+ :add-text (plist-get opt-plist :text))
+ "\n"))
+ thetoc have-headings first-heading-pos
+ table-open table-buffer)
+
+ (let ((inhibit-read-only t))
+ (org-unmodified
+ (remove-text-properties (point-min) (point-max)
+ '(:org-license-to-kill t))))
+
+ (setq org-min-level (org-get-min-level lines))
+ (setq org-last-level org-min-level)
(org-init-section-numbers)
(find-file-noselect filename)
(fundamental-mode)
;; create local variables for all options, to make sure all called
;; functions get the correct information
- (mapcar (lambda (x)
- (set (make-local-variable (cdr x))
- (plist-get opt-plist (car x))))
- org-export-plist-vars)
+ (mapc (lambda (x)
+ (set (make-local-variable (cdr x))
+ (plist-get opt-plist (car x))))
+ org-export-plist-vars)
(org-set-local 'org-odd-levels-only odd)
(setq umax (if arg (prefix-numeric-value arg)
org-export-headline-levels))
;; File header
(if title (org-insert-centered title ?=))
(insert "\n")
- (if (or author email)
+ (if (and (or author email)
+ org-export-author-info)
(insert (concat (nth 1 lang-words) ": " (or author "")
(if email (concat " <" email ">") "")
"\n")))
- (if (and date time)
- (insert (concat (nth 2 lang-words) ": " date " " time "\n")))
- (if text (insert (concat (org-html-expand-for-ascii text) "\n\n")))
+
+ (cond
+ ((and date (string-match "%" date))
+ (setq date (format-time-string date (current-time))))
+ (date)
+ (t (setq date (format-time-string "%Y/%m/%d %X" (current-time)))))
+
+ (if (and date org-export-time-stamp-file)
+ (insert (concat (nth 2 lang-words) ": " date"\n")))
(insert "\n\n")
(if org-export-with-toc
(progn
- (insert (nth 3 lang-words) "\n"
- (make-string (length (nth 3 lang-words)) ?=) "\n")
- (mapcar '(lambda (line)
- (if (string-match org-todo-line-regexp
- line)
- ;; This is a headline
- (progn
- (setq level (- (match-end 1) (match-beginning 1))
- level (org-tr-level level)
- txt (match-string 3 line)
- todo
- (or (and org-export-mark-todo-in-toc
- (match-beginning 2)
- (not (equal (match-string 2 line)
- org-done-string)))
+ (push (concat (nth 3 lang-words) "\n") thetoc)
+ (push (concat (make-string (length (nth 3 lang-words)) ?=) "\n") thetoc)
+ (mapc '(lambda (line)
+ (if (string-match org-todo-line-regexp
+ line)
+ ;; This is a headline
+ (progn
+ (setq have-headings t)
+ (setq level (- (match-end 1) (match-beginning 1))
+ level (org-tr-level level)
+ txt (match-string 3 line)
+ todo
+ (or (and org-export-mark-todo-in-toc
+ (match-beginning 2)
+ (not (member (match-string 2 line)
+ org-done-keywords)))
; TODO, not DONE
- (and org-export-mark-todo-in-toc
- (= level umax-toc)
- (org-search-todo-below
- line lines level))))
- (setq txt (org-html-expand-for-ascii txt))
-
- (if (and (memq org-export-with-tags '(not-in-toc nil))
- (string-match "[ \t]+:[a-zA-Z0-9_@:]+:[ \t]*$" txt))
- (setq txt (replace-match "" t t txt)))
- (if (string-match quote-re0 txt)
- (setq txt (replace-match "" t t txt)))
-
- (if org-export-with-section-numbers
- (setq txt (concat (org-section-number level)
- " " txt)))
- (if (<= level umax-toc)
- (progn
- (insert
- (make-string (* (1- level) 4) ?\ )
- (format (if todo "%s (*)\n" "%s\n") txt))
- (setq org-last-level level))
- ))))
- lines)))
+ (and org-export-mark-todo-in-toc
+ (= level umax-toc)
+ (org-search-todo-below
+ line lines level))))
+ (setq txt (org-html-expand-for-ascii txt))
+
+ (while (string-match org-bracket-link-regexp txt)
+ (setq txt
+ (replace-match
+ (match-string (if (match-end 2) 3 1) txt)
+ t t txt)))
+
+ (if (and (memq org-export-with-tags '(not-in-toc nil))
+ (string-match
+ (org-re "[ \t]+:[[:alnum:]_@:]+:[ \t]*$")
+ txt))
+ (setq txt (replace-match "" t t txt)))
+ (if (string-match quote-re0 txt)
+ (setq txt (replace-match "" t t txt)))
+
+ (if org-export-with-section-numbers
+ (setq txt (concat (org-section-number level)
+ " " txt)))
+ (if (<= level umax-toc)
+ (progn
+ (push
+ (concat
+ (make-string
+ (* (max 0 (- level org-min-level)) 4) ?\ )
+ (format (if todo "%s (*)\n" "%s\n") txt))
+ thetoc)
+ (setq org-last-level level))
+ ))))
+ lines)
+ (setq thetoc (if have-headings (nreverse thetoc) nil))))
(org-init-section-numbers)
(while (setq line (pop lines))
(when custom-times
(setq line (org-translate-time line)))
(cond
- ((string-match "^\\(\\*+\\)[ \t]*\\(.*\\)" line)
+ ((string-match "^\\(\\*+\\)[ \t]+\\(.*\\)" line)
;; a Headline
+ (setq first-heading-pos (or first-heading-pos (point)))
(setq level (org-tr-level (- (match-end 1) (match-beginning 1)))
txt (match-string 2 line))
(org-ascii-level-start level txt umax lines))
+
+ ((and org-export-with-tables
+ (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)" line))
+ (if (not table-open)
+ ;; New table starts
+ (setq table-open t table-buffer nil))
+ ;; Accumulate lines
+ (setq table-buffer (cons line table-buffer))
+ (when (or (not lines)
+ (not (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)"
+ (car lines))))
+ (setq table-open nil
+ table-buffer (nreverse table-buffer))
+ (insert (mapconcat
+ (lambda (x)
+ (org-fix-indentation x org-ascii-current-indentation))
+ (org-format-table-ascii table-buffer)
+ "\n") "\n")))
(t
- (insert (org-fix-indentation line org-ascii-current-indentation) "\n"))))
+ (setq line (org-fix-indentation line org-ascii-current-indentation))
+ (if (and org-export-with-fixed-width
+ (string-match "^\\([ \t]*\\)\\(:\\)" line))
+ (setq line (replace-match "\\1" nil nil line)))
+ (insert line "\n"))))
+
(normal-mode)
+
+ ;; insert the table of contents
+ (when thetoc
+ (goto-char (point-min))
+ (if (re-search-forward "^[ \t]*\\[TABLE-OF-CONTENTS\\][ \t]*$" nil t)
+ (progn
+ (goto-char (match-beginning 0))
+ (replace-match ""))
+ (goto-char first-heading-pos))
+ (mapc 'insert thetoc)
+ (or (looking-at "[ \t]*\n[ \t]*\n")
+ (insert "\n\n")))
+
+ ;; Convert whitespace place holders
+ (goto-char (point-min))
+ (let (beg end)
+ (while (setq beg (next-single-property-change (point) 'org-whitespace))
+ (setq end (next-single-property-change beg 'org-whitespace))
+ (goto-char beg)
+ (delete-region beg end)
+ (insert (make-string (- end beg) ?\ ))))
+
(save-buffer)
;; remove display and invisible chars
(let (beg end)
(goto-char beg)))
(goto-char (point-min))))
+(defun org-export-ascii-clean-string ()
+ "Do extra work for ASCII export"
+ (goto-char (point-min))
+ (while (re-search-forward org-verbatim-re nil t)
+ (goto-char (match-end 2))
+ (backward-delete-char 1) (insert "'")
+ (goto-char (match-beginning 2))
+ (delete-char 1) (insert "`")
+ (goto-char (match-end 2))))
+
(defun org-search-todo-below (line lines level)
"Search the subtree below LINE for any TODO entries."
(let ((rest (cdr (memq line lines)))
(progn
(setq lv (- (match-end 1) (match-beginning 1))
todo (and (match-beginning 2)
- (not (equal (match-string 2 line)
- org-done-string))))
+ (not (member (match-string 2 line)
+ org-done-keywords))))
; TODO, not DONE
(if (<= lv level) (throw 'exit nil))
(if todo (throw 'exit t))))))))
;; find the indentation of the next non-empty line
(catch 'stop
(while lines
- (if (string-match "^\\*" (car lines)) (throw 'stop nil))
+ (if (string-match "^\\* " (car lines)) (throw 'stop nil))
(if (string-match "^\\([ \t]*\\)\\S-" (car lines))
(throw 'stop (setq ind (org-get-indentation (car lines)))))
(pop lines)))
(insert "\n"))
(setq char (nth (- umax level) (reverse org-export-ascii-underline)))
(unless org-export-with-tags
- (if (string-match "[ \t]+\\(:[a-zA-Z0-9_@:]+:\\)[ \t]*$" title)
+ (if (string-match (org-re "[ \t]+\\(:[[:alnum:]_@:]+:\\)[ \t]*$") title)
(setq title (replace-match "" t t title))))
(if org-export-with-section-numbers
(setq title (concat (org-section-number level) " " title)))
command."
(interactive
(list (progn
- (message "Export visible: [a]SCII [h]tml [b]rowse HTML [x]OXO [ ]keep buffer")
+ (message "Export visible: [a]SCII [h]tml [b]rowse HTML [H/R]uffer with HTML [x]OXO [ ]keep buffer")
(read-char-exclusive))
current-prefix-arg))
(if (not (member type '(?a ?\C-a ?b ?\C-b ?h ?x ?\ )))
(?b . org-export-as-html-and-open)
(?\C-b . org-export-as-html-and-open)
(?h . org-export-as-html)
+ (?H . org-export-as-html-to-buffer)
+ (?R . org-export-region-as-html)
(?x . org-export-as-xoxo)))))
(keepp (equal type ?\ ))
(file buffer-file-name)
(buffer (get-buffer-create "*Org Export Visible*"))
s e)
+ ;; Need to hack the drawers here.
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward org-drawer-regexp nil t)
+ (goto-char (match-beginning 1))
+ (or (org-invisible-p) (org-flag-drawer nil))))
(with-current-buffer buffer (erase-buffer))
(save-excursion
(setq s (goto-char (point-min)))
(goto-char (org-find-invisible))
(append-to-buffer buffer s (point))
(setq s (goto-char (org-find-visible))))
+ (org-cycle-hide-drawers 'all)
(goto-char (point-min))
(unless keepp
;; Copy all comment lines to the end, to make sure #+ settings are
#+EMAIL: %s
#+LANGUAGE: %s
#+TEXT: Some descriptive text to be emitted. Several lines OK.
-#+OPTIONS: H:%d num:%s toc:%s \\n:%s @:%s ::%s |:%s ^:%s *:%s TeX:%s LaTeX:%s
+#+OPTIONS: H:%d num:%s toc:%s \\n:%s @:%s ::%s |:%s ^:%s -:%s f:%s *:%s TeX:%s LaTeX:%s skip:%s d:%s tags:%s
#+CATEGORY: %s
#+SEQ_TODO: %s
#+TYP_TODO: %s
+#+PRIORITIES: %c %c %c
+#+DRAWERS: %s
#+STARTUP: %s %s %s %s %s
#+TAGS: %s
#+ARCHIVE: %s
org-export-with-fixed-width
org-export-with-tables
org-export-with-sub-superscripts
+ org-export-with-special-strings
+ org-export-with-footnotes
org-export-with-emphasize
org-export-with-TeX-macros
org-export-with-LaTeX-fragments
+ org-export-skip-text-before-1st-heading
+ org-export-with-drawers
+ org-export-with-tags
(file-name-nondirectory buffer-file-name)
- (if (equal org-todo-interpretation 'sequence)
- (mapconcat 'identity org-todo-keywords " ")
- "TODO FEEDBACK VERIFY DONE")
- (if (equal org-todo-interpretation 'type)
- (mapconcat 'identity org-todo-keywords " ")
- "Me Jason Marie DONE")
+ "TODO FEEDBACK VERIFY DONE"
+ "Me Jason Marie DONE"
+ org-highest-priority org-lowest-priority org-default-priority
+ (mapconcat 'identity org-drawers " ")
(cdr (assoc org-startup-folded
'((nil . "showall") (t . "overview") (content . "content"))))
(if org-odd-levels-only "odd" "oddeven")
(if org-hide-leading-stars "hidestars" "showstars")
(if org-startup-align-all-tables "align" "noalign")
- (cond ((eq t org-log-done) "logdone")
- ((not org-log-done) "nologging")
- ((listp org-log-done)
- (mapconcat (lambda (x) (concat "lognote" (symbol-name x)))
- org-log-done " ")))
+ (cond ((eq org-log-done t) "logdone")
+ ((equal org-log-done 'note) "lognotedone")
+ ((not org-log-done) "nologdone"))
(or (mapconcat (lambda (x)
(cond
((equal '(:startgroup) x) "{")
(beg (if regionp (region-beginning) (point)))
(end (if regionp (region-end)))
(nlines (or arg (if (and beg end) (count-lines beg end) 1)))
+ (case-fold-search nil)
(re "[ \t]*\\(:\\)")
off)
(if regionp
(save-excursion
(org-back-to-heading)
(if (looking-at (concat outline-regexp
- "\\( +\\<" org-quote-string "\\>\\)"))
+ "\\( *\\<" org-quote-string "\\>[ \t]*\\)"))
(replace-match "" t t nil 1)
(if (looking-at outline-regexp)
(progn
(goto-char (match-end 0))
- (insert " " org-quote-string))))))))
+ (insert org-quote-string " "))))))))
(defun org-export-as-html-and-open (arg)
"Export the outline as HTML and immediately open it with a browser.
--visit=MyFile --funcall org-export-as-html-batch"
(org-export-as-html org-export-headline-levels 'hidden))
-(defun org-export-as-html (arg &optional hidden ext-plist)
+(defun org-export-as-html-to-buffer (arg)
+ "Call `org-exort-as-html` with output to a temporary buffer.
+No file is created. The prefix ARG is passed through to `org-export-as-html'."
+ (interactive "P")
+ (org-export-as-html arg nil nil "*Org HTML Export*")
+ (switch-to-buffer-other-window "*Org HTML Export*"))
+
+(defun org-replace-region-by-html (beg end)
+ "Assume the current region has org-mode syntax, and convert it to HTML.
+This can be used in any buffer. For example, you could write an
+itemized list in org-mode syntax in an HTML buffer and then use this
+command to convert it."
+ (interactive "r")
+ (let (reg html buf pop-up-frames)
+ (save-window-excursion
+ (if (org-mode-p)
+ (setq html (org-export-region-as-html
+ beg end t 'string))
+ (setq reg (buffer-substring beg end)
+ buf (get-buffer-create "*Org tmp*"))
+ (with-current-buffer buf
+ (erase-buffer)
+ (insert reg)
+ (org-mode)
+ (setq html (org-export-region-as-html
+ (point-min) (point-max) t 'string)))
+ (kill-buffer buf)))
+ (delete-region beg end)
+ (insert html)))
+
+(defun org-export-region-as-html (beg end &optional body-only buffer)
+ "Convert region from BEG to END in org-mode buffer to HTML.
+If prefix arg BODY-ONLY is set, omit file header, footer, and table of
+contents, and only produce the region of converted text, useful for
+cut-and-paste operations.
+If BUFFER is a buffer or a string, use/create that buffer as a target
+of the converted HTML. If BUFFER is the symbol `string', return the
+produced HTML as a string and leave not buffer behind. For example,
+a Lisp program could call this function in the following way:
+
+ (setq html (org-export-region-as-html beg end t 'string))
+
+When called interactively, the output buffer is selected, and shown
+in a window. A non-interactive call will only retunr the buffer."
+ (interactive "r\nP")
+ (when (interactive-p)
+ (setq buffer "*Org HTML Export*"))
+ (let ((transient-mark-mode t) (zmacs-regions t)
+ rtn)
+ (goto-char end)
+ (set-mark (point)) ;; to activate the region
+ (goto-char beg)
+ (setq rtn (org-export-as-html
+ nil nil nil
+ buffer body-only))
+ (if (fboundp 'deactivate-mark) (deactivate-mark))
+ (if (and (interactive-p) (bufferp rtn))
+ (switch-to-buffer-other-window rtn)
+ rtn)))
+
+(defvar html-table-tag nil) ; dynamically scoped into this.
+(defun org-export-as-html (arg &optional hidden ext-plist
+ to-buffer body-only pub-dir)
"Export the outline as a pretty HTML file.
-If there is an active region, export only the region.
-The prefix ARG specifies how many levels of the outline should become
-headlines. The default is 3. Lower levels will become bulleted lists.
-When HIDDEN is non-nil, don't display the HTML buffer.
+If there is an active region, export only the region. The prefix
+ARG specifies how many levels of the outline should become
+headlines. The default is 3. Lower levels will become bulleted
+lists. When HIDDEN is non-nil, don't display the HTML buffer.
EXT-PLIST is a property list with external parameters overriding
-org-mode's default settings, but still inferior to file-local settings."
+org-mode's default settings, but still inferior to file-local
+settings. When TO-BUFFER is non-nil, create a buffer with that
+name and export to that buffer. If TO-BUFFER is the symbol
+`string', don't leave any buffer behind but just return the
+resulting HTML as a string. When BODY-ONLY is set, don't produce
+the file header and footer, simply return the content of
+<body>...</body>, without even the body tags themselves. When
+PUB-DIR is set, use this as the publishing directory."
(interactive "P")
+
+ ;; Make sure we have a file name when we need it.
+ (when (and (not (or to-buffer body-only))
+ (not buffer-file-name))
+ (if (buffer-base-buffer)
+ (org-set-local 'buffer-file-name
+ (with-current-buffer (buffer-base-buffer)
+ buffer-file-name))
+ (error "Need a file name to be able to export.")))
+
(message "Exporting...")
(setq-default org-todo-line-regexp org-todo-line-regexp)
(setq-default org-deadline-line-regexp org-deadline-line-regexp)
- (setq-default org-done-string org-done-string)
+ (setq-default org-done-keywords org-done-keywords)
(setq-default org-maybe-keyword-time-regexp org-maybe-keyword-time-regexp)
(let* ((opt-plist (org-combine-plists (org-default-export-plist)
ext-plist
(org-infile-export-plist)))
(style (plist-get opt-plist :style))
+ (html-extension (plist-get opt-plist :html-extension))
(link-validate (plist-get opt-plist :link-validation-function))
- valid
+ valid thetoc have-headings first-heading-pos
(odd org-odd-levels-only)
(region-p (org-region-active-p))
- (region
- (buffer-substring
- (if region-p (region-beginning) (point-min))
- (if region-p (region-end) (point-max))))
+ (subtree-p
+ (when region-p
+ (save-excursion
+ (goto-char (region-beginning))
+ (and (org-at-heading-p)
+ (>= (org-end-of-subtree t t) (region-end))))))
;; The following two are dynamically scoped into other
;; routines below.
- (org-current-export-dir (org-export-directory :html opt-plist))
+ (org-current-export-dir
+ (or pub-dir (org-export-directory :html opt-plist)))
(org-current-export-file buffer-file-name)
- (all_lines
- (org-skip-comments (org-split-string
- (org-cleaned-string-for-export
- region :emph-multiline :for-html
- (if (plist-get opt-plist :LaTeX-fragments)
- :LaTeX-fragments))
- "[\r\n]")))
- (lines (org-export-find-first-heading-line all_lines))
(level 0) (line "") (origline "") txt todo
(umax nil)
(umax-toc nil)
- (filename (concat (file-name-as-directory
- (org-export-directory :html opt-plist))
- (file-name-sans-extension
- (file-name-nondirectory buffer-file-name))
- ".html"))
- (current-dir (file-name-directory buffer-file-name))
- (buffer (find-file-noselect filename))
+ (filename (if to-buffer nil
+ (expand-file-name
+ (concat
+ (file-name-sans-extension
+ (or (and subtree-p
+ (org-entry-get (region-beginning)
+ "EXPORT_FILE_NAME" t))
+ (file-name-nondirectory buffer-file-name)))
+ "." html-extension)
+ (file-name-as-directory
+ (or pub-dir (org-export-directory :html opt-plist))))))
+ (current-dir (if buffer-file-name
+ (file-name-directory buffer-file-name)
+ default-directory))
+ (buffer (if to-buffer
+ (cond
+ ((eq to-buffer 'string) (get-buffer-create "*Org HTML Export*"))
+ (t (get-buffer-create to-buffer)))
+ (find-file-noselect filename)))
(org-levels-open (make-vector org-level-max nil))
- (date (format-time-string "%Y/%m/%d" (current-time)))
- (time (format-time-string "%X" (org-current-time)))
+ (date (plist-get opt-plist :date))
(author (plist-get opt-plist :author))
- (title (or (plist-get opt-plist :title)
- (file-name-sans-extension
- (file-name-nondirectory buffer-file-name))))
+ (title (or (and subtree-p (org-export-get-title-from-subtree))
+ (plist-get opt-plist :title)
+ (and (not
+ (plist-get opt-plist :skip-before-1st-heading))
+ (org-export-grab-title-from-buffer))
+ (and buffer-file-name
+ (file-name-sans-extension
+ (file-name-nondirectory buffer-file-name)))
+ "UNTITLED"))
+ (html-table-tag (plist-get opt-plist :html-table-tag))
(quote-re0 (concat "^[ \t]*" org-quote-string "\\>"))
- (quote-re (concat "^\\(\\*+\\)\\([ \t]*" org-quote-string "\\>\\)"))
+ (quote-re (concat "^\\(\\*+\\)\\([ \t]+" org-quote-string "\\>\\)"))
(inquote nil)
(infixed nil)
(in-local-list nil)
(llt org-plain-list-ordered-item-terminator)
(email (plist-get opt-plist :email))
(language (plist-get opt-plist :language))
- (text (plist-get opt-plist :text))
(lang-words nil)
(target-alist nil) tg
(head-count 0) cnt
(start 0)
(coding-system (and (boundp 'buffer-file-coding-system)
buffer-file-coding-system))
- (coding-system-for-write coding-system)
- (save-buffer-coding-system coding-system)
- (charset (and coding-system
+ (coding-system-for-write (or org-export-html-coding-system
+ coding-system))
+ (save-buffer-coding-system (or org-export-html-coding-system
+ coding-system))
+ (charset (and coding-system-for-write
(fboundp 'coding-system-get)
- (coding-system-get coding-system 'mime-charset)))
+ (coding-system-get coding-system-for-write
+ 'mime-charset)))
+ (region
+ (buffer-substring
+ (if region-p (region-beginning) (point-min))
+ (if region-p (region-end) (point-max))))
+ (lines
+ (org-split-string
+ (org-cleaned-string-for-export
+ region
+ :emph-multiline t
+ :for-html t
+ :skip-before-1st-heading
+ (plist-get opt-plist :skip-before-1st-heading)
+ :drawers (plist-get opt-plist :drawers)
+ :archived-trees
+ (plist-get opt-plist :archived-trees)
+ :add-text
+ (plist-get opt-plist :text)
+ :LaTeX-fragments
+ (plist-get opt-plist :LaTeX-fragments))
+ "[\r\n]"))
table-open type
table-buffer table-orig-buffer
- ind start-is-num starter
+ ind start-is-num starter didclose
rpl path desc descp desc1 desc2 link
)
+
+ (let ((inhibit-read-only t))
+ (org-unmodified
+ (remove-text-properties (point-min) (point-max)
+ '(:org-license-to-kill t))))
+
(message "Exporting...")
- (setq org-last-level 1)
+ (setq org-min-level (org-get-min-level lines))
+ (setq org-last-level org-min-level)
(org-init-section-numbers)
+ (cond
+ ((and date (string-match "%" date))
+ (setq date (format-time-string date (current-time))))
+ (date)
+ (t (setq date (format-time-string "%Y/%m/%d %X" (current-time)))))
+
;; Get the language-dependent settings
(setq lang-words (or (assoc language org-export-language-setup)
(assoc "en" org-export-language-setup)))
;; Switch to the output buffer
- (if (or hidden t)
- (set-buffer buffer)
- (switch-to-buffer-other-window buffer))
- (erase-buffer)
+ (set-buffer buffer)
+ (let ((inhibit-read-only t)) (erase-buffer))
(fundamental-mode)
+
+ (and (fboundp 'set-buffer-file-coding-system)
+ (set-buffer-file-coding-system coding-system-for-write))
+
(let ((case-fold-search nil)
(org-odd-levels-only odd))
;; create local variables for all options, to make sure all called
;; functions get the correct information
- (mapcar (lambda (x)
- (set (make-local-variable (cdr x))
- (plist-get opt-plist (car x))))
- org-export-plist-vars)
+ (mapc (lambda (x)
+ (set (make-local-variable (cdr x))
+ (plist-get opt-plist (car x))))
+ org-export-plist-vars)
(setq umax (if arg (prefix-numeric-value arg)
org-export-headline-levels))
(setq umax-toc (if (integerp org-export-with-toc)
(min org-export-with-toc umax)
umax))
-
- ;; File header
- (insert (format
- "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
+ (unless body-only
+ ;; File header
+ (insert (format
+ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\"
lang=\"%s\" xml:lang=\"%s\">
<title>%s</title>
<meta http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"/>
<meta name=\"generator\" content=\"Org-mode\"/>
-<meta name=\"generated\" content=\"%s %s\"/>
+<meta name=\"generated\" content=\"%s\"/>
<meta name=\"author\" content=\"%s\"/>
%s
</head><body>
"
- language language (org-html-expand title) (or charset "iso-8859-1")
- date time author style))
-
+ language language (org-html-expand title)
+ (or charset "iso-8859-1") date author style))
- (insert (or (plist-get opt-plist :preamble) ""))
+ (insert (or (plist-get opt-plist :preamble) ""))
- (when (plist-get opt-plist :auto-preamble)
- (if title (insert (format org-export-html-title-format
- (org-html-expand title))))
- (if text (insert "<p>\n" (org-html-expand text) "</p>")))
+ (when (plist-get opt-plist :auto-preamble)
+ (if title (insert (format org-export-html-title-format
+ (org-html-expand title))))))
- (if org-export-with-toc
+ (if (and org-export-with-toc (not body-only))
(progn
- (insert (format "<h%d>%s</h%d>\n"
- org-export-html-toplevel-hlevel
- (nth 3 lang-words)
- org-export-html-toplevel-hlevel))
- (insert "<ul>\n<li>")
+ (push (format "<h%d>%s</h%d>\n"
+ org-export-html-toplevel-hlevel
+ (nth 3 lang-words)
+ org-export-html-toplevel-hlevel)
+ thetoc)
+ (push "<ul>\n<li>" thetoc)
(setq lines
- (mapcar '(lambda (line)
- (if (string-match org-todo-line-regexp line)
- ;; This is a headline
- (progn
- (setq level (- (match-end 1) (match-beginning 1))
- level (org-tr-level level)
- txt (save-match-data
- (org-html-expand
- (org-export-cleanup-toc-line
- (match-string 3 line))))
- todo
- (or (and org-export-mark-todo-in-toc
- (match-beginning 2)
- (not (equal (match-string 2 line)
- org-done-string)))
+ (mapcar '(lambda (line)
+ (if (string-match org-todo-line-regexp line)
+ ;; This is a headline
+ (progn
+ (setq have-headings t)
+ (setq level (- (match-end 1) (match-beginning 1))
+ level (org-tr-level level)
+ txt (save-match-data
+ (org-html-expand
+ (org-export-cleanup-toc-line
+ (match-string 3 line))))
+ todo
+ (or (and org-export-mark-todo-in-toc
+ (match-beginning 2)
+ (not (member (match-string 2 line)
+ org-done-keywords)))
; TODO, not DONE
- (and org-export-mark-todo-in-toc
- (= level umax-toc)
- (org-search-todo-below
- line lines level))))
- (if (and (memq org-export-with-tags '(not-in-toc nil))
- (string-match "[ \t]+:[a-zA-Z0-9_@:]+:[ \t]*$" txt))
- (setq txt (replace-match "" t t txt)))
- (if (string-match quote-re0 txt)
- (setq txt (replace-match "" t t txt)))
- (if org-export-with-section-numbers
- (setq txt (concat (org-section-number level)
- " " txt)))
- (if (<= level umax-toc)
- (progn
- (setq head-count (+ head-count 1))
- (if (> level org-last-level)
- (progn
- (setq cnt (- level org-last-level))
- (while (>= (setq cnt (1- cnt)) 0)
- (insert "\n<ul>\n<li>"))
- (insert "\n")))
- (if (< level org-last-level)
- (progn
- (setq cnt (- org-last-level level))
- (while (>= (setq cnt (1- cnt)) 0)
- (insert "</li>\n</ul>"))
- (insert "\n")))
- ;; Check for targets
- (while (string-match org-target-regexp line)
- (setq tg (match-string 1 line)
- line (replace-match
- (concat "@<span class=\"target\">" tg "@</span> ")
- t t line))
- (push (cons (org-solidify-link-text tg)
- (format "sec-%d" head-count))
- target-alist))
- (while (string-match "<\\(<\\)+\\|>\\(>\\)+" txt)
- (setq txt (replace-match "" t t txt)))
- (insert
- (format
- (if todo
- "</li>\n<li><a href=\"#sec-%d\"><span class=\"todo\">%s</span></a>"
- "</li>\n<li><a href=\"#sec-%d\">%s</a>")
- head-count txt))
-
- (setq org-last-level level))
- )))
- line)
- lines))
- (while (> org-last-level 0)
+ (and org-export-mark-todo-in-toc
+ (= level umax-toc)
+ (org-search-todo-below
+ line lines level))))
+ (if (string-match
+ (org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$") txt)
+ (setq txt (replace-match " <span class=\"tag\"> \\1</span>" t nil txt)))
+ (if (string-match quote-re0 txt)
+ (setq txt (replace-match "" t t txt)))
+ (if org-export-with-section-numbers
+ (setq txt (concat (org-section-number level)
+ " " txt)))
+ (if (<= level (max umax umax-toc))
+ (setq head-count (+ head-count 1)))
+ (if (<= level umax-toc)
+ (progn
+ (if (> level org-last-level)
+ (progn
+ (setq cnt (- level org-last-level))
+ (while (>= (setq cnt (1- cnt)) 0)
+ (push "\n<ul>\n<li>" thetoc))
+ (push "\n" thetoc)))
+ (if (< level org-last-level)
+ (progn
+ (setq cnt (- org-last-level level))
+ (while (>= (setq cnt (1- cnt)) 0)
+ (push "</li>\n</ul>" thetoc))
+ (push "\n" thetoc)))
+ ;; Check for targets
+ (while (string-match org-target-regexp line)
+ (setq tg (match-string 1 line)
+ line (replace-match
+ (concat "@<span class=\"target\">" tg "@</span> ")
+ t t line))
+ (push (cons (org-solidify-link-text tg)
+ (format "sec-%d" head-count))
+ target-alist))
+ (while (string-match "<\\(<\\)+\\|>\\(>\\)+" txt)
+ (setq txt (replace-match "" t t txt)))
+ (push
+ (format
+ (if todo
+ "</li>\n<li><a href=\"#sec-%d\"><span class=\"todo\">%s</span></a>"
+ "</li>\n<li><a href=\"#sec-%d\">%s</a>")
+ head-count txt) thetoc)
+
+ (setq org-last-level level))
+ )))
+ line)
+ lines))
+ (while (> org-last-level (1- org-min-level))
(setq org-last-level (1- org-last-level))
- (insert "</li>\n</ul>\n"))
- ))
+ (push "</li>\n</ul>\n" thetoc))
+ (setq thetoc (if have-headings (nreverse thetoc) nil))))
+
(setq head-count 0)
(org-init-section-numbers)
(catch 'nextline
;; end of quote section?
- (when (and inquote (string-match "^\\*+" line))
+ (when (and inquote (string-match "^\\*+ " line))
(insert "</pre>\n")
(setq inquote nil))
;; inside a quote section?
;; Protected HTML
(when (get-text-property 0 'org-protected line)
- (insert line "\n")
+ (let (par)
+ (when (re-search-backward
+ "\\(<p>\\)\\([ \t\r\n]*\\)\\=" (- (point) 100) t)
+ (setq par (match-string 1))
+ (replace-match "\\2\n"))
+ (insert line "\n")
+ (while (and lines
+ (or (= (length (car lines)) 0)
+ (get-text-property 0 'org-protected (car lines))))
+ (insert (pop lines) "\n"))
+ (and par (insert "<p>\n")))
(throw 'nextline nil))
;; Horizontal line
;; replace "&" by "&", "<" and ">" by "<" and ">"
;; handle @<..> HTML tags (replace "@>..<" by "<..>")
;; Also handle sub_superscripts and checkboxes
- (setq line (org-html-expand line))
+ (or (string-match org-table-hline-regexp line)
+ (setq line (org-html-expand line)))
;; Format the links
(setq start 0)
(setq rpl
(concat
"<a href=\"#"
- (org-solidify-link-text path target-alist)
+ (org-solidify-link-text
+ (save-match-data (org-link-unescape path)) target-alist)
"\">" desc "</a>")))
- ((member type '("http" "https")) ; FIXME: need to test this.
+ ((member type '("http" "https"))
;; standard URL, just check if we need to inline an image
(if (and (or (eq t org-export-html-inline-images)
(and org-export-html-inline-images (not descp)))
(string-match "\\.org$" thefile))
(setq thefile (concat (substring thefile 0
(match-beginning 0))
- ".html"))
+ "." html-extension))
(if (and search
;; make sure this is can be used as target search
(not (string-match "^[0-9]*$" search))
"></i>"))))
(setq line (replace-match rpl t t line)
start (+ start (length rpl))))
+
;; TODO items
(if (and (string-match org-todo-line-regexp line)
(match-beginning 2))
- (if (equal (match-string 2 line) org-done-string)
- (setq line (replace-match
- "<span class=\"done\">\\2</span>"
- t nil line 2))
- (setq line (replace-match "<span class=\"todo\">\\2</span>"
- t nil line 2))))
+
+ (setq line
+ (concat (substring line 0 (match-beginning 2))
+ "<span class=\""
+ (if (member (match-string 2 line)
+ org-done-keywords)
+ "done" "todo")
+ "\">" (match-string 2 line)
+ "</span>" (substring line (match-end 2)))))
+
+ ;; Does this contain a reference to a footnote?
+ (when org-export-with-footnotes
+ (setq start 0)
+ (while (string-match "\\([^* \t].*?\\)\\[\\([0-9]+\\)\\]" line start)
+ (if (get-text-property (match-beginning 2) 'org-protected line)
+ (setq start (match-end 2))
+ (let ((n (match-string 2 line)))
+ (setq line
+ (replace-match
+ (format
+ "%s<sup><a class=\"footref\" name=\"fnr.%s\" href=\"#fn.%s\">%s</a></sup>"
+ (match-string 1 line) n n n)
+ t t line))))))
(cond
- ((string-match "^\\(\\*+\\)[ \t]*\\(.*\\)" line)
+ ((string-match "^\\(\\*+\\)[ \t]+\\(.*\\)" line)
;; This is a headline
(setq level (org-tr-level (- (match-end 1) (match-beginning 1)))
txt (match-string 2 line))
(if (string-match quote-re0 txt)
(setq txt (replace-match "" t t txt)))
- (if (<= level umax) (setq head-count (+ head-count 1)))
+ (if (<= level (max umax umax-toc))
+ (setq head-count (+ head-count 1)))
(when in-local-list
;; Close any local lists before inserting a new header line
(while local-list-num
(pop local-list-num))
(setq local-list-indent nil
in-local-list nil))
+ (setq first-heading-pos (or first-heading-pos (point)))
(org-html-level-start level txt umax
(and org-export-with-toc (<= level umax))
head-count)
(cond
((eq llt t) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+[.)]\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
((= llt ?.) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+\\.\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
- ((= llt ?\)) "^\\( \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+)\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
+ ((= llt ?\)) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+)\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
(t (error "Invalid value of `org-plain-list-ordered-item-terminator'")))
line)
(setq ind (org-get-string-indentation line)
line (substring line (match-beginning 5)))
(unless (string-match "[^ \t]" line)
;; empty line. Pretend indentation is large.
- (setq ind (1+ (or (car local-list-indent) 1))))
+ (setq ind (if org-empty-line-terminates-plain-lists
+ 0
+ (1+ (or (car local-list-indent) 1)))))
+ (setq didclose nil)
(while (and in-local-list
(or (and (= ind (car local-list-indent))
(not starter))
(< ind (car local-list-indent))))
+ (setq didclose t)
(org-close-li)
(insert (if (car local-list-num) "</ol>\n" "</ul>"))
(pop local-list-num) (pop local-list-indent)
((and starter
(or (not in-local-list)
(> ind (car local-list-indent))))
- ;; Start new (level of ) list
+ ;; Start new (level of) list
(org-close-par-maybe)
(insert (if start-is-num "<ol>\n<li>\n" "<ul>\n<li>\n"))
(push start-is-num local-list-num)
(starter
;; continue current list
(org-close-li)
- (insert "<li>\n")))
+ (insert "<li>\n"))
+ (didclose
+ ;; we did close a list, normal text follows: need <p>
+ (org-open-par)))
(if (string-match "^[ \t]*\\[\\([X ]\\)\\]" line)
(setq line
(replace-match
;; also start a new paragraph.
(if (string-match "^ [-+*]-\\|^[ \t]*$" line) (org-open-par))
+ ;; Is this the start of a footnote?
+ (when org-export-with-footnotes
+ (when (string-match "^[ \t]*\\[\\([0-9]+\\)\\]" line)
+ (org-close-par-maybe)
+ (let ((n (match-string 1 line)))
+ (setq line (replace-match
+ (format "<p class=\"footnote\"><sup><a class=\"footnum\" name=\"fn.%s\" href=\"#fnr.%s\">%s</a></sup>" n n n) t t line)))))
+
;; Check if the line break needs to be conserved
(cond
((string-match "\\\\\\\\[ \t]*$" line)
(and org-export-with-toc (<= level umax))
head-count)
- (when (plist-get opt-plist :auto-postamble)
- (when author
- (insert "<p class=\"author\"> "
- (nth 1 lang-words) ": " author "\n")
- (when email
- (insert "<a href=\"mailto:" email "\"><"
- email "></a>\n"))
- (insert "</p>\n"))
- (when (and date time)
- (insert "<p class=\"date\"> "
- (nth 2 lang-words) ": "
- date " " time "</p>\n")))
-
- (if org-export-html-with-timestamp
- (insert org-export-html-html-helper-timestamp))
- (insert (or (plist-get opt-plist :postamble) ""))
- (insert "</body>\n</html>\n")
+ (unless body-only
+ (when (plist-get opt-plist :auto-postamble)
+ (insert "<div id=\"postamble\">")
+ (when (and org-export-author-info author)
+ (insert "<p class=\"author\"> "
+ (nth 1 lang-words) ": " author "\n")
+ (when email
+ (if (listp (split-string email ",+ *"))
+ (mapc (lambda(e)
+ (insert "<a href=\"mailto:" e "\"><"
+ e "></a>\n"))
+ (split-string email ",+ *"))
+ (insert "<a href=\"mailto:" email "\"><"
+ email "></a>\n")))
+ (insert "</p>\n"))
+ (when (and date org-export-time-stamp-file)
+ (insert "<p class=\"date\"> "
+ (nth 2 lang-words) ": "
+ date "</p>\n"))
+ (insert "</div>"))
+
+ (if org-export-html-with-timestamp
+ (insert org-export-html-html-helper-timestamp))
+ (insert (or (plist-get opt-plist :postamble) ""))
+ (insert "</body>\n</html>\n"))
+
(normal-mode)
+ (if (eq major-mode default-major-mode) (html-mode))
+
+ ;; insert the table of contents
+ (goto-char (point-min))
+ (when thetoc
+ (if (or (re-search-forward
+ "<p>\\s-*\\[TABLE-OF-CONTENTS\\]\\s-*</p>" nil t)
+ (re-search-forward
+ "\\[TABLE-OF-CONTENTS\\]" nil t))
+ (progn
+ (goto-char (match-beginning 0))
+ (replace-match ""))
+ (goto-char first-heading-pos)
+ (when (looking-at "\\s-*</p>")
+ (goto-char (match-end 0))
+ (insert "\n")))
+ (insert "<div id=\"table-of-contents\">\n")
+ (mapc 'insert thetoc)
+ (insert "</div>\n"))
;; remove empty paragraphs and lists
(goto-char (point-min))
(while (re-search-forward "<p>[ \r\n\t]*</p>" nil t)
(replace-match ""))
(goto-char (point-min))
- (while (re-search-forward "<li>[ \r\n\t]*</li>\n?" nil t)
+ (while (re-search-forward "<li>[ \r\n\t]*</li>\n?" nil t)
+ (replace-match ""))
+ (goto-char (point-min))
+ (while (re-search-forward "</ul>\\s-*<ul>\n?" nil t)
(replace-match ""))
- (save-buffer)
+ ;; Convert whitespace place holders
(goto-char (point-min))
- (message "Exporting... done"))))
-
+ (let (beg end n)
+ (while (setq beg (next-single-property-change (point) 'org-whitespace))
+ (setq n (get-text-property beg 'org-whitespace)
+ end (next-single-property-change beg 'org-whitespace))
+ (goto-char beg)
+ (delete-region beg end)
+ (insert (format "<span style=\"visibility:hidden;\">%s</span>"
+ (make-string n ?x)))))
+ (or to-buffer (save-buffer))
+ (goto-char (point-min))
+ (message "Exporting... done")
+ (if (eq to-buffer 'string)
+ (prog1 (buffer-substring (point-min) (point-max))
+ (kill-buffer (current-buffer)))
+ (current-buffer)))))
+
+(defvar org-table-colgroup-info nil)
+(defun org-format-table-ascii (lines)
+ "Format a table for ascii export."
+ (if (stringp lines)
+ (setq lines (org-split-string lines "\n")))
+ (if (not (string-match "^[ \t]*|" (car lines)))
+ ;; Table made by table.el - test for spanning
+ lines
+
+ ;; A normal org table
+ ;; Get rid of hlines at beginning and end
+ (if (string-match "^[ \t]*|-" (car lines)) (setq lines (cdr lines)))
+ (setq lines (nreverse lines))
+ (if (string-match "^[ \t]*|-" (car lines)) (setq lines (cdr lines)))
+ (setq lines (nreverse lines))
+ (when org-export-table-remove-special-lines
+ ;; Check if the table has a marking column. If yes remove the
+ ;; column and the special lines
+ (setq lines (org-table-clean-before-export lines)))
+ ;; Get rid of the vertical lines except for grouping
+ (let ((vl (org-colgroup-info-to-vline-list org-table-colgroup-info))
+ rtn line vl1 start)
+ (while (setq line (pop lines))
+ (if (string-match org-table-hline-regexp line)
+ (and (string-match "|\\(.*\\)|" line)
+ (setq line (replace-match " \\1" t nil line)))
+ (setq start 0 vl1 vl)
+ (while (string-match "|" line start)
+ (setq start (match-end 0))
+ (or (pop vl1) (setq line (replace-match " " t t line)))))
+ (push line rtn))
+ (nreverse rtn))))
+
+(defun org-colgroup-info-to-vline-list (info)
+ (let (vl new last)
+ (while info
+ (setq last new new (pop info))
+ (if (or (memq last '(:end :startend))
+ (memq new '(:start :startend)))
+ (push t vl)
+ (push nil vl)))
+ (setq vl (nreverse vl))
+ (and vl (setcar vl nil))
+ vl))
(defun org-format-table-html (lines olines)
"Find out which HTML converter to use and return the HTML code."
+ (if (stringp lines)
+ (setq lines (org-split-string lines "\n")))
(if (string-match "^[ \t]*|" (car lines))
;; A normal org table
(org-format-org-table-html lines)
(lambda (x) (string-match "^[ \t]*|-" x))
(cdr lines)))))
(nlines 0) fnum i
- tbopen line fields html)
+ tbopen line fields html gr colgropen)
(if splice (setq head nil))
(unless splice (push (if head "<thead>" "<tbody>") html))
(setq tbopen t)
(string-match org-table-number-regexp x))
(incf (aref fnum i)))
(if head
- (concat "<th>" x "</th>")
- (concat "<td>" x "</td>")))
+ (concat (car org-export-table-header-tags) x
+ (cdr org-export-table-header-tags))
+ (concat (car org-export-table-data-tags) x
+ (cdr org-export-table-data-tags))))
fields "")
"</tr>")
html)))
(unless splice (push "</table>\n" html))
(setq html (nreverse html))
(unless splice
- ;; Put in COL tags with the alignment (unfortuntely often ignored...)
+ ;; Put in col tags with the alignment (unfortuntely often ignored...)
(push (mapconcat
(lambda (x)
- (format "<COL align=\"%s\">"
+ (setq gr (pop org-table-colgroup-info))
+ (format "%s<col align=\"%s\"></col>%s"
+ (if (memq gr '(:start :startend))
+ (prog1
+ (if colgropen "</colgroup>\n<colgroup>" "<colgroup>")
+ (setq colgropen t))
+ "")
(if (> (/ (float x) nlines) org-table-number-fraction)
- "right" "left")))
+ "right" "left")
+ (if (memq gr '(:end :startend))
+ (progn (setq colgropen nil) "</colgroup>")
+ "")))
fnum "")
html)
- (push org-export-html-table-tag html))
+ (if colgropen (setq html (cons (car html) (cons "</colgroup>" (cdr html)))))
+ (push html-table-tag html))
(concat (mapconcat 'identity html "\n") "\n")))
(defun org-table-clean-before-export (lines)
"Check if the table has a marking column.
If yes remove the column and the special lines."
+ (setq org-table-colgroup-info nil)
(if (memq nil
(mapcar
(lambda (x) (or (string-match "^[ \t]*|-" x)
(string-match "^[ \t]*| *\\([#!$*_^ /]\\) *|" x)))
lines))
(progn
- (setq org-table-clean-did-remove-column-1 nil)
- lines)
- (setq org-table-clean-did-remove-column-1 t)
+ (setq org-table-clean-did-remove-column nil)
+ (delq nil
+ (mapcar
+ (lambda (x)
+ (cond
+ ((string-match "^[ \t]*| */ *|" x)
+ (setq org-table-colgroup-info
+ (mapcar (lambda (x)
+ (cond ((member x '("<" "<")) :start)
+ ((member x '(">" ">")) :end)
+ ((member x '("<>" "<>")) :startend)
+ (t nil)))
+ (org-split-string x "[ \t]*|[ \t]*")))
+ nil)
+ (t x)))
+ lines)))
+ (setq org-table-clean-did-remove-column t)
(delq nil
(mapcar
- (lambda (x) (if (string-match "^[ \t]*| *[!_^/] *|" x)
- nil ; ignore this line
- (and (or (string-match "^[ \t]*|-+\\+" x)
- (string-match "^[ \t]*|[^|]*|" x))
- (replace-match "|" t t x))))
+ (lambda (x)
+ (cond
+ ((string-match "^[ \t]*| */ *|" x)
+ (setq org-table-colgroup-info
+ (mapcar (lambda (x)
+ (cond ((member x '("<" "<")) :start)
+ ((member x '(">" ">")) :end)
+ ((member x '("<>" "<>")) :startend)
+ (t nil)))
+ (cdr (org-split-string x "[ \t]*|[ \t]*"))))
+ nil)
+ ((string-match "^[ \t]*| *[!_^/] *|" x)
+ nil) ; ignore this line
+ ((or (string-match "^\\([ \t]*\\)|-+\\+" x)
+ (string-match "^\\([ \t]*\\)|[^|]*|" x))
+ ;; remove the first column
+ (replace-match "\\1|" t nil x))))
lines))))
-(defun org-fake-empty-table-line (line)
- "Replace everything except \"|\" with spaces."
- (let ((i (length line))
- (newstr (copy-sequence line)))
- (while (> i 0)
- (setq i (1- i))
- (if (not (eq (aref newstr i) ?|))
- (aset newstr i ?\ )))
- newstr))
-
(defun org-format-table-table-html (lines)
"Format a table generated by table.el into HTML.
This conversion does *not* use `table-generate-source' from table.el.
(let (line field-buffer
(head org-export-highlight-first-table-line)
fields html empty)
- (setq html (concat org-export-html-table-tag "\n"))
+ (setq html (concat html-table-tag "\n"))
(while (setq line (pop lines))
(setq empty " ")
(catch 'next-line
(progn
(if field-buffer
(progn
- (setq html (concat
- html
- "<tr>"
- (mapconcat
- (lambda (x)
- (if (equal x "") (setq x empty))
- (if head
- (concat "<th>" x "</th>\n")
- (concat "<td>" x "</td>\n")))
- field-buffer "\n")
- "</tr>\n"))
+ (setq
+ html
+ (concat
+ html
+ "<tr>"
+ (mapconcat
+ (lambda (x)
+ (if (equal x "") (setq x empty))
+ (if head
+ (concat (car org-export-table-header-tags) x
+ (cdr org-export-table-header-tags))
+ (concat (car org-export-table-data-tags) x
+ (cdr org-export-table-data-tags))))
+ field-buffer "\n")
+ "</tr>\n"))
(setq head nil)
(setq field-buffer nil)))
;; Ignore this line
(defun org-export-cleanup-toc-line (s)
"Remove tags and time staps from lines going into the toc."
- (if (string-match " +:[a-zA-Z0-9_@:]+: *$" s)
- (setq s (replace-match "" t t s)))
+ (when (memq org-export-with-tags '(not-in-toc nil))
+ (if (string-match (org-re " +:[[:alnum:]_@:]+: *$") s)
+ (setq s (replace-match "" t t s))))
(when org-export-remove-timestamps-from-toc
(while (string-match org-maybe-keyword-time-regexp s)
(setq s (replace-match "" t t s))))
+ (while (string-match org-bracket-link-regexp s)
+ (setq s (replace-match (match-string (if (match-end 3) 3 1) s)
+ t t s)))
s)
(defun org-html-expand (string)
"Prepare STRING for HTML export. Applies all active conversions.
If there are links in the string, don't modify these."
- (let* (m s l res)
- (while (setq m (string-match org-bracket-link-regexp string))
+ (let* ((re (concat org-bracket-link-regexp "\\|"
+ (org-re "[ \t]+\\(:[[:alnum:]_@:]+:\\)[ \t]*$")))
+ m s l res)
+ (while (setq m (string-match re string))
(setq s (substring string 0 m)
l (match-string 0 string)
string (substring string (match-end 0)))
"Apply all active conversions to translate special ASCII to HTML."
(setq s (org-html-protect s))
(if org-export-html-expand
- (while (string-match "@<\\([^&]*\\)>" s)
- (setq s (replace-match "<\\1>" t nil s))))
+ (let ((start 0))
+ (while (string-match "@<\\([^&]*\\)>" s)
+ (setq s (replace-match "<\\1>" t nil s)))))
(if org-export-with-emphasize
(setq s (org-export-html-convert-emphasize s)))
+ (if org-export-with-special-strings
+ (setq s (org-export-html-convert-special-strings s)))
(if org-export-with-sub-superscripts
(setq s (org-export-html-convert-sub-super s)))
(if org-export-with-TeX-macros
(let ((start 0) wd ass)
(while (setq start (string-match "\\\\\\([a-zA-Z]+\\)" s start))
- (setq wd (match-string 1 s))
- (if (setq ass (assoc wd org-html-entities))
- (setq s (replace-match (or (cdr ass)
- (concat "&" (car ass) ";"))
- t t s))
- (setq start (+ start (length wd)))))))
+ (if (get-text-property (match-beginning 0) 'org-protected s)
+ (setq start (match-end 0))
+ (setq wd (match-string 1 s))
+ (if (setq ass (assoc wd org-html-entities))
+ (setq s (replace-match (or (cdr ass)
+ (concat "&" (car ass) ";"))
+ t t s))
+ (setq start (+ start (length wd))))))))
s)
(defun org-create-multibrace-regexp (left right n)
"\\(\\(?:\\*\\|[-+]?[^-+*!@#$%^_ \t\r\n,:\"?<>~;./{}=()]+\\)\\)\\)")
"The regular expression matching a sub- or superscript.")
+(defvar org-match-substring-with-braces-regexp
+ (concat
+ "\\([^\\]\\)\\([_^]\\)\\("
+ "\\(" (org-create-multibrace-regexp "{" "}" org-match-sexp-depth) "\\)"
+ "\\)")
+ "The regular expression matching a sub- or superscript, forcing braces.")
+
+(defconst org-export-html-special-string-regexps
+ '(("\\\\-" . "­")
+ ("---\\([^-]\\)" . "—\\1")
+ ("--\\([^-]\\)" . "–\\1")
+ ("\\.\\.\\." . "…"))
+ "Regular expressions for special string conversion.")
+
+(defun org-export-html-convert-special-strings (string)
+ "Convert special characters in STRING to HTML."
+ (let ((all org-export-html-special-string-regexps)
+ e a re rpl start)
+ (while (setq a (pop all))
+ (setq re (car a) rpl (cdr a) start 0)
+ (while (string-match re string start)
+ (if (get-text-property (match-beginning 0) 'org-protected string)
+ (setq start (match-end 0))
+ (setq string (replace-match rpl t nil string)))))
+ string))
+
(defun org-export-html-convert-sub-super (string)
"Convert sub- and superscripts in STRING to HTML."
- (let (key c)
- (while (string-match org-match-substring-regexp string)
- (setq key (if (string= (match-string 2 string) "_") "sub" "sup"))
- (setq c (or (match-string 8 string)
- (match-string 6 string)
- (match-string 5 string)))
- (setq string (replace-match
- (concat (match-string 1 string)
- "<" key ">" c "</" key ">")
- t t string)))
+ (let (key c (s 0) (requireb (eq org-export-with-sub-superscripts '{})))
+ (while (string-match org-match-substring-regexp string s)
+ (cond
+ ((and requireb (match-end 8)) (setq s (match-end 2)))
+ ((get-text-property (match-beginning 2) 'org-protected string)
+ (setq s (match-end 2)))
+ (t
+ (setq s (match-end 1)
+ key (if (string= (match-string 2 string) "_") "sub" "sup")
+ c (or (match-string 8 string)
+ (match-string 6 string)
+ (match-string 5 string))
+ string (replace-match
+ (concat (match-string 1 string)
+ "<" key ">" c "</" key ">")
+ t t string)))))
(while (string-match "\\\\\\([_^]\\)" string)
- (setq string (replace-match (match-string 1 string) t t string))))
- string)
+ (setq string (replace-match (match-string 1 string) t t string)))
+ string))
(defun org-export-html-convert-emphasize (string)
"Apply emphasis."
- (while (string-match org-emph-re string)
- (setq string (replace-match (concat "\\1" (nth 2 (assoc (match-string 3 string) org-emphasis-alist)) "\\4" (nth 3 (assoc (match-string 3 string) org-emphasis-alist)) "\\5") t nil string)))
- string)
+ (let ((s 0) rpl)
+ (while (string-match org-emph-re string s)
+ (if (not (equal
+ (substring string (match-beginning 3) (1+ (match-beginning 3)))
+ (substring string (match-beginning 4) (1+ (match-beginning 4)))))
+ (setq s (match-beginning 0)
+ rpl
+ (concat
+ (match-string 1 string)
+ (nth 2 (assoc (match-string 3 string) org-emphasis-alist))
+ (match-string 4 string)
+ (nth 3 (assoc (match-string 3 string)
+ org-emphasis-alist))
+ (match-string 5 string))
+ string (replace-match rpl t t string)
+ s (+ s (- (length rpl) 2)))
+ (setq s (1+ s))))
+ string))
(defvar org-par-open nil)
(defun org-open-par ()
"Close <li> if necessary."
(org-close-par-maybe)
(insert "</li>\n"))
-; (when (save-excursion
-; (re-search-backward "</?\\(ul\\|ol\\|li\\|[hH][0-9]\\)>" nil t))
-; (if (member (match-string 0) '("</ul>" "</ol>" "<li>"))
-; (insert "</li>"))))
+(defvar body-only) ; dynamically scoped into this.
(defun org-html-level-start (level title umax with-toc head-count)
"Insert a new level in HTML export.
When TITLE is nil, just close all open levels."
(org-close-par-maybe)
- (let ((l (1+ (max level umax))))
- (while (<= l org-level-max)
+ (let ((l org-level-max))
+ (while (>= l level)
(if (aref org-levels-open (1- l))
(progn
- (org-html-level-close l)
+ (org-html-level-close l umax)
(aset org-levels-open (1- l) nil)))
- (setq l (1+ l)))
+ (setq l (1- l)))
(when title
;; If title is nil, this means this function is called to close
;; all levels, so the rest is done only if title is given
- (when (string-match "\\(:[a-zA-Z0-9_@:]+:\\)[ \t]*$" title)
+ (when (string-match (org-re "\\(:[[:alnum:]_@:]+:\\)[ \t]*$") title)
(setq title (replace-match
(if org-export-with-tags
(save-match-data
(aset org-levels-open (1- level) t)
(org-close-par-maybe)
(insert "<ul>\n<li>" title "<br/>\n")))
- (if org-export-with-section-numbers
+ (aset org-levels-open (1- level) t)
+ (if (and org-export-with-section-numbers (not body-only))
(setq title (concat (org-section-number level) " " title)))
(setq level (+ level org-export-html-toplevel-hlevel -1))
(if with-toc
- (insert (format "\n<h%d><a name=\"sec-%d\">%s</a></h%d>\n"
- level head-count title level))
- (insert (format "\n<h%d>%s</h%d>\n" level title level)))
+ (insert (format "\n<div class=\"outline-%d\">\n<h%d id=\"sec-%d\">%s</h%d>\n"
+ level level head-count title level))
+ (insert (format "\n<div class=\"outline-%d\">\n<h%d>%s</h%d>\n" level level title level)))
(org-open-par)))))
-(defun org-html-level-close (&rest args)
+(defun org-html-level-close (level max-outline-level)
"Terminate one level in HTML export."
- (org-close-li)
- (insert "</ul>"))
+ (if (<= level max-outline-level)
+ (insert "</div>\n")
+ (org-close-li)
+ (insert "</ul>\n")))
;;; iCalendar export
If COMBINE is non-nil, combine all calendar entries into a single large
file and store it under the name `org-combined-agenda-icalendar-file'."
(save-excursion
+ (org-prepare-agenda-buffers files)
(let* ((dir (org-export-directory
:ical (list :publishing-directory
org-export-publishing-directory)))
file ical-file ical-buffer category started org-agenda-new-buffers)
-
+ (and (get-buffer "*ical-tmp*") (kill-buffer "*ical-tmp*"))
(when combine
(setq ical-file
(if (file-name-absolute-p org-combined-agenda-icalendar-file)
(defun org-print-icalendar-entries (&optional combine)
"Print iCalendar entries for the current Org-mode file to `standard-output'.
When COMBINE is non nil, add the category to each line."
- (let ((re2 (concat "--?-?\\(" org-ts-regexp "\\)"))
- (org-category-table (org-get-category-table))
+ (let ((re1 (concat org-ts-regexp "\\|<%%([^>\n]+>"))
+ (re2 (concat "--?-?\\(" org-ts-regexp "\\)"))
(dts (org-ical-ts-to-string
(format-time-string (cdr org-time-stamp-formats) (current-time))
"DTSTART"))
- hd ts ts2 state status (inc t) pos
- scheduledp deadlinep tmp pri category)
+ hd ts ts2 state status (inc t) pos b sexp rrule
+ scheduledp deadlinep tmp pri category entry location summary desc
+ (sexp-buffer (get-buffer-create "*ical-tmp*")))
+ (org-refresh-category-properties)
(save-excursion
(goto-char (point-min))
- (while (re-search-forward org-ts-regexp nil t)
- (setq pos (match-beginning 0)
- ts (match-string 0)
- inc t
- hd (org-get-heading)
- category (org-get-category))
- (if (looking-at re2)
- (progn
- (goto-char (match-end 0))
- (setq ts2 (match-string 1) inc nil))
- (setq ts2 ts
- tmp (buffer-substring (max (point-min)
+ (while (re-search-forward re1 nil t)
+ (catch :skip
+ (org-agenda-skip)
+ (when (boundp 'org-icalendar-verify-function)
+ (unless (funcall org-icalendar-verify-function)
+ (outline-next-heading)
+ (backward-char 1)
+ (throw :skip nil)))
+ (setq pos (match-beginning 0)
+ ts (match-string 0)
+ inc t
+ hd (org-get-heading)
+ summary (org-icalendar-cleanup-string
+ (org-entry-get nil "SUMMARY"))
+ desc (org-icalendar-cleanup-string
+ (or (org-entry-get nil "DESCRIPTION")
+ (and org-icalendar-include-body (org-get-entry)))
+ t org-icalendar-include-body)
+ location (org-icalendar-cleanup-string
+ (org-entry-get nil "LOCATION"))
+ category (org-get-category))
+ (if (looking-at re2)
+ (progn
+ (goto-char (match-end 0))
+ (setq ts2 (match-string 1) inc nil))
+ (setq tmp (buffer-substring (max (point-min)
(- pos org-ds-keyword-length))
- pos)
- deadlinep (string-match org-deadline-regexp tmp)
- scheduledp (string-match org-scheduled-regexp tmp)
- ;; donep (org-entry-is-done-p)
- ))
- (if (or (string-match org-tr-regexp hd)
- (string-match org-ts-regexp hd))
- (setq hd (replace-match "" t t hd)))
- (if (string-match org-bracket-link-regexp hd)
- (setq hd (replace-match (if (match-end 3) (match-string 3 hd)
- (match-string 1 hd))
- t t hd)))
- (if deadlinep (setq hd (concat "DL: " hd)))
- (if scheduledp (setq hd (concat "S: " hd)))
- (princ (format "BEGIN:VEVENT
+ pos)
+ ts2 (if (string-match "[0-9]\\{1,2\\}:[0-9][0-9]-\\([0-9]\\{1,2\\}:[0-9][0-9]\\)" ts)
+ (progn
+ (setq inc nil)
+ (replace-match "\\1" t nil ts))
+ ts)
+ deadlinep (string-match org-deadline-regexp tmp)
+ scheduledp (string-match org-scheduled-regexp tmp)
+ ;; donep (org-entry-is-done-p)
+ ))
+ (if (or (string-match org-tr-regexp hd)
+ (string-match org-ts-regexp hd))
+ (setq hd (replace-match "" t t hd)))
+ (if (string-match "\\+\\([0-9]+\\)\\([dwmy]\\)>" ts)
+ (setq rrule
+ (concat "\nRRULE:FREQ="
+ (cdr (assoc
+ (match-string 2 ts)
+ '(("d" . "DAILY")("w" . "WEEKLY")
+ ("m" . "MONTHLY")("y" . "YEARLY"))))
+ ";INTERVAL=" (match-string 1 ts)))
+ (setq rrule ""))
+ (setq summary (or summary hd))
+ (if (string-match org-bracket-link-regexp summary)
+ (setq summary
+ (replace-match (if (match-end 3)
+ (match-string 3 summary)
+ (match-string 1 summary))
+ t t summary)))
+ (if deadlinep (setq summary (concat "DL: " summary)))
+ (if scheduledp (setq summary (concat "S: " summary)))
+ (if (string-match "\\`<%%" ts)
+ (with-current-buffer sexp-buffer
+ (insert (substring ts 1 -1) " " summary "\n"))
+ (princ (format "BEGIN:VEVENT
%s
-%s
-SUMMARY:%s
+%s%s
+SUMMARY:%s%s%s
CATEGORIES:%s
END:VEVENT\n"
- (org-ical-ts-to-string ts "DTSTART")
- (org-ical-ts-to-string ts2 "DTEND" inc)
- hd category)))
+ (org-ical-ts-to-string ts "DTSTART")
+ (org-ical-ts-to-string ts2 "DTEND" inc)
+ rrule summary
+ (if (and desc (string-match "\\S-" desc))
+ (concat "\nDESCRIPTION: " desc) "")
+ (if (and location (string-match "\\S-" location))
+ (concat "\nLOCATION: " location) "")
+ category)))))
+
+ (when (and org-icalendar-include-sexps
+ (condition-case nil (require 'icalendar) (error nil))
+ (fboundp 'icalendar-export-region))
+ ;; Get all the literal sexps
+ (goto-char (point-min))
+ (while (re-search-forward "^&?%%(" nil t)
+ (catch :skip
+ (org-agenda-skip)
+ (setq b (match-beginning 0))
+ (goto-char (1- (match-end 0)))
+ (forward-sexp 1)
+ (end-of-line 1)
+ (setq sexp (buffer-substring b (point)))
+ (with-current-buffer sexp-buffer
+ (insert sexp "\n"))
+ (princ (org-diary-to-ical-string sexp-buffer)))))
+
(when org-icalendar-include-todo
(goto-char (point-min))
(while (re-search-forward org-todo-line-regexp nil t)
- (setq state (match-string 2))
- (setq status (if (equal state org-done-string)
- "COMPLETED" "NEEDS-ACTION"))
- (when (and state
- (or (not (equal state org-done-string))
- (eq org-icalendar-include-todo 'all)))
- (setq hd (match-string 3))
- (if (string-match org-priority-regexp hd)
- (setq pri (string-to-char (match-string 2 hd))
- hd (concat (substring hd 0 (match-beginning 1))
- (substring hd (match-end 1))))
- (setq pri org-default-priority))
- (setq pri (floor (1+ (* 8. (/ (float (- org-lowest-priority pri))
- (- org-lowest-priority ?A))))))
-
- (princ (format "BEGIN:VTODO
+ (catch :skip
+ (org-agenda-skip)
+ (when (boundp 'org-icalendar-verify-function)
+ (unless (funcall org-icalendar-verify-function)
+ (outline-next-heading)
+ (backward-char 1)
+ (throw :skip nil)))
+ (setq state (match-string 2))
+ (setq status (if (member state org-done-keywords)
+ "COMPLETED" "NEEDS-ACTION"))
+ (when (and state
+ (or (not (member state org-done-keywords))
+ (eq org-icalendar-include-todo 'all))
+ (not (member org-archive-tag (org-get-tags-at)))
+ )
+ (setq hd (match-string 3)
+ summary (org-icalendar-cleanup-string
+ (org-entry-get nil "SUMMARY"))
+ desc (org-icalendar-cleanup-string
+ (or (org-entry-get nil "DESCRIPTION")
+ (and org-icalendar-include-body (org-get-entry)))
+ t org-icalendar-include-body)
+ location (org-icalendar-cleanup-string
+ (org-entry-get nil "LOCATION")))
+ (if (string-match org-bracket-link-regexp hd)
+ (setq hd (replace-match (if (match-end 3) (match-string 3 hd)
+ (match-string 1 hd))
+ t t hd)))
+ (if (string-match org-priority-regexp hd)
+ (setq pri (string-to-char (match-string 2 hd))
+ hd (concat (substring hd 0 (match-beginning 1))
+ (substring hd (match-end 1))))
+ (setq pri org-default-priority))
+ (setq pri (floor (1+ (* 8. (/ (float (- org-lowest-priority pri))
+ (- org-lowest-priority org-highest-priority))))))
+
+ (princ (format "BEGIN:VTODO
%s
-SUMMARY:%s
+SUMMARY:%s%s%s
CATEGORIES:%s
SEQUENCE:1
PRIORITY:%d
STATUS:%s
END:VTODO\n"
- dts hd category pri status))))))))
+ dts
+ (or summary hd)
+ (if (and location (string-match "\\S-" location))
+ (concat "\nLOCATION: " location) "")
+ (if (and desc (string-match "\\S-" desc))
+ (concat "\nDESCRIPTION: " desc) "")
+ category pri status)))))))))
+
+(defun org-icalendar-cleanup-string (s &optional is-body maxlength)
+ "Take out stuff and quote what needs to be quoted.
+When IS-BODY is non-nil, assume that this is the body of an item, clean up
+whitespace, newlines, drawers, and timestamps, and cut it down to MAXLENGTH
+characters."
+ (if (not s)
+ nil
+ (when is-body
+ (let ((re (concat "\\(" org-drawer-regexp "\\)[^\000]*?:END:.*\n?"))
+ (re2 (concat "^[ \t]*" org-keyword-time-regexp ".*\n?")))
+ (while (string-match re s) (setq s (replace-match "" t t s)))
+ (while (string-match re2 s) (setq s (replace-match "" t t s)))))
+ (let ((start 0))
+ (while (string-match "\\([,;\\]\\)" s start)
+ (setq start (+ (match-beginning 0) 2)
+ s (replace-match "\\\\\\1" nil nil s))))
+ (when is-body
+ (while (string-match "[ \t]*\n[ \t]*" s)
+ (setq s (replace-match "\\n" t t s))))
+ (setq s (org-trim s))
+ (if is-body
+ (if maxlength
+ (if (and (numberp maxlength)
+ (> (length s) maxlength))
+ (setq s (substring s 0 maxlength)))))
+ s))
+
+(defun org-get-entry ()
+ "Clean-up description string."
+ (save-excursion
+ (org-back-to-heading t)
+ (buffer-substring (point-at-bol 2) (org-end-of-subtree t))))
(defun org-start-icalendar-file (name)
"Start an iCalendar file by inserting the header."
(let ((s (car t2)) (mi (nth 1 t2)) (h (nth 2 t2))
(d (nth 3 t2)) (m (nth 4 t2)) (y (nth 5 t2)))
(when inc
- (if have-time (setq h (+ 2 h)) (setq d (1+ d))))
+ (if have-time
+ (if org-agenda-default-appointment-duration
+ (setq mi (+ org-agenda-default-appointment-duration mi))
+ (setq h (+ 2 h)))
+ (setq d (1+ d))))
(setq time (encode-time s mi h d m y)))
(setq fmt (if have-time ":%Y%m%dT%H%M%S" ";VALUE=DATE:%Y%m%d"))
(concat keyword (format-time-string fmt time))))
;; Output everything as XOXO
(with-current-buffer (get-buffer buffer)
- (goto-char (point-min)) ;; CD: beginning-of-buffer is not allowed.
- (let* ((opt-plist (org-combine-plists (org-default-export-plist)
+ (let* ((pos (point))
+ (opt-plist (org-combine-plists (org-default-export-plist)
(org-infile-export-plist)))
(filename (concat (file-name-as-directory
(org-export-directory :xoxo opt-plist))
(out (find-file-noselect filename))
(last-level 1)
(hanging-li nil))
+ (goto-char (point-min)) ;; CD: beginning-of-buffer is not allowed.
;; Check the output buffer is empty.
(with-current-buffer out (erase-buffer))
;; Kick off the output
(org-export-as-xoxo-insert-into out "<ol class='xoxo'>\n")
- (while (re-search-forward "^\\(\\*+\\) \\(.+\\)" (point-max) 't)
+ (while (re-search-forward "^\\(\\*+\\)[ \t]+\\(.+\\)" (point-max) 't)
(let* ((hd (match-string-no-properties 1))
(level (length hd))
(text (concat
(org-export-as-xoxo-insert-into out "</li>\n"))
(org-export-as-xoxo-insert-into out "</ol>\n"))
+ (goto-char pos)
;; Finish the buffer off and clean it up.
(switch-to-buffer-other-window out)
(indent-region (point-min) (point-max) nil)
;;;; Key bindings
-;; - Bindings in Org-mode map are currently
-;; 0123456789abcdefghijklmnopqrstuvwxyz!?@#$%^&-+*/=()_{}[]:;"|,.<>~`'\t the alphabet
-;; abcd fgh j lmnopqrstuvwxyz!? #$ ^ -+*/= [] ; |,.<>~ '\t necessary bindings
-;; e (?) useful from outline-mode
-;; i k @ expendable from outline-mode
-;; 0123456789 % & ()_{} " ` free
-
;; Make `C-c C-x' a prefix key
-(define-key org-mode-map "\C-c\C-x" (make-sparse-keymap))
+(org-defkey org-mode-map "\C-c\C-x" (make-sparse-keymap))
;; TAB key with modifiers
-(define-key org-mode-map "\C-i" 'org-cycle)
-(define-key org-mode-map [(tab)] 'org-cycle)
-(define-key org-mode-map [(control tab)] 'org-force-cycle-archived)
-(define-key org-mode-map [(meta tab)] 'org-complete)
-(define-key org-mode-map "\M-\t" 'org-complete)
-(define-key org-mode-map "\M-\C-i" 'org-complete)
+(org-defkey org-mode-map "\C-i" 'org-cycle)
+(org-defkey org-mode-map [(tab)] 'org-cycle)
+(org-defkey org-mode-map [(control tab)] 'org-force-cycle-archived)
+(org-defkey org-mode-map [(meta tab)] 'org-complete)
+(org-defkey org-mode-map "\M-\t" 'org-complete)
+(org-defkey org-mode-map "\M-\C-i" 'org-complete)
;; The following line is necessary under Suse GNU/Linux
(unless (featurep 'xemacs)
- (define-key org-mode-map [S-iso-lefttab] 'org-shifttab))
-(define-key org-mode-map [(shift tab)] 'org-shifttab)
+ (org-defkey org-mode-map [S-iso-lefttab] 'org-shifttab))
+(org-defkey org-mode-map [(shift tab)] 'org-shifttab)
+(define-key org-mode-map [backtab] 'org-shifttab)
-(define-key org-mode-map (org-key 'S-return) 'org-table-copy-down)
-(define-key org-mode-map [(meta shift return)] 'org-insert-todo-heading)
-(define-key org-mode-map [(meta return)] 'org-meta-return)
+(org-defkey org-mode-map [(shift return)] 'org-table-copy-down)
+(org-defkey org-mode-map [(meta shift return)] 'org-insert-todo-heading)
+(org-defkey org-mode-map [(meta return)] 'org-meta-return)
;; Cursor keys with modifiers
-(define-key org-mode-map [(meta left)] 'org-metaleft)
-(define-key org-mode-map [(meta right)] 'org-metaright)
-(define-key org-mode-map [(meta up)] 'org-metaup)
-(define-key org-mode-map [(meta down)] 'org-metadown)
+(org-defkey org-mode-map [(meta left)] 'org-metaleft)
+(org-defkey org-mode-map [(meta right)] 'org-metaright)
+(org-defkey org-mode-map [(meta up)] 'org-metaup)
+(org-defkey org-mode-map [(meta down)] 'org-metadown)
-(define-key org-mode-map [(meta shift left)] 'org-shiftmetaleft)
-(define-key org-mode-map [(meta shift right)] 'org-shiftmetaright)
-(define-key org-mode-map [(meta shift up)] 'org-shiftmetaup)
-(define-key org-mode-map [(meta shift down)] 'org-shiftmetadown)
+(org-defkey org-mode-map [(meta shift left)] 'org-shiftmetaleft)
+(org-defkey org-mode-map [(meta shift right)] 'org-shiftmetaright)
+(org-defkey org-mode-map [(meta shift up)] 'org-shiftmetaup)
+(org-defkey org-mode-map [(meta shift down)] 'org-shiftmetadown)
-(define-key org-mode-map (org-key 'S-up) 'org-shiftup)
-(define-key org-mode-map (org-key 'S-down) 'org-shiftdown)
-(define-key org-mode-map (org-key 'S-left) 'org-shiftleft)
-(define-key org-mode-map (org-key 'S-right) 'org-shiftright)
+(org-defkey org-mode-map [(shift up)] 'org-shiftup)
+(org-defkey org-mode-map [(shift down)] 'org-shiftdown)
+(org-defkey org-mode-map [(shift left)] 'org-shiftleft)
+(org-defkey org-mode-map [(shift right)] 'org-shiftright)
+
+(org-defkey org-mode-map [(control shift right)] 'org-shiftcontrolright)
+(org-defkey org-mode-map [(control shift left)] 'org-shiftcontrolleft)
;;; Extra keys for tty access.
;; We only set them when really needed because otherwise the
(when (or (featurep 'xemacs) ;; because XEmacs supports multi-device stuff
(not window-system))
- (define-key org-mode-map "\C-c\C-xc" 'org-table-copy-down)
- (define-key org-mode-map "\C-c\C-xM" 'org-insert-todo-heading)
- (define-key org-mode-map "\C-c\C-xm" 'org-meta-return)
- (define-key org-mode-map [?\e (return)] 'org-meta-return)
- (define-key org-mode-map [?\e (left)] 'org-metaleft)
- (define-key org-mode-map "\C-c\C-xl" 'org-metaleft)
- (define-key org-mode-map [?\e (right)] 'org-metaright)
- (define-key org-mode-map "\C-c\C-xr" 'org-metaright)
- (define-key org-mode-map [?\e (up)] 'org-metaup)
- (define-key org-mode-map "\C-c\C-xu" 'org-metaup)
- (define-key org-mode-map [?\e (down)] 'org-metadown)
- (define-key org-mode-map "\C-c\C-xd" 'org-metadown)
- (define-key org-mode-map "\C-c\C-xL" 'org-shiftmetaleft)
- (define-key org-mode-map "\C-c\C-xR" 'org-shiftmetaright)
- (define-key org-mode-map "\C-c\C-xU" 'org-shiftmetaup)
- (define-key org-mode-map "\C-c\C-xD" 'org-shiftmetadown)
- (define-key org-mode-map [?\C-c ?\C-x (up)] 'org-shiftup)
- (define-key org-mode-map [?\C-c ?\C-x (down)] 'org-shiftdown)
- (define-key org-mode-map [?\C-c ?\C-x (left)] 'org-shiftleft)
- (define-key org-mode-map [?\C-c ?\C-x (right)] 'org-shiftright))
+ (org-defkey org-mode-map "\C-c\C-xc" 'org-table-copy-down)
+ (org-defkey org-mode-map "\C-c\C-xM" 'org-insert-todo-heading)
+ (org-defkey org-mode-map "\C-c\C-xm" 'org-meta-return)
+ (org-defkey org-mode-map [?\e (return)] 'org-meta-return)
+ (org-defkey org-mode-map [?\e (left)] 'org-metaleft)
+ (org-defkey org-mode-map "\C-c\C-xl" 'org-metaleft)
+ (org-defkey org-mode-map [?\e (right)] 'org-metaright)
+ (org-defkey org-mode-map "\C-c\C-xr" 'org-metaright)
+ (org-defkey org-mode-map [?\e (up)] 'org-metaup)
+ (org-defkey org-mode-map "\C-c\C-xu" 'org-metaup)
+ (org-defkey org-mode-map [?\e (down)] 'org-metadown)
+ (org-defkey org-mode-map "\C-c\C-xd" 'org-metadown)
+ (org-defkey org-mode-map "\C-c\C-xL" 'org-shiftmetaleft)
+ (org-defkey org-mode-map "\C-c\C-xR" 'org-shiftmetaright)
+ (org-defkey org-mode-map "\C-c\C-xU" 'org-shiftmetaup)
+ (org-defkey org-mode-map "\C-c\C-xD" 'org-shiftmetadown)
+ (org-defkey org-mode-map [?\C-c (up)] 'org-shiftup)
+ (org-defkey org-mode-map [?\C-c (down)] 'org-shiftdown)
+ (org-defkey org-mode-map [?\C-c (left)] 'org-shiftleft)
+ (org-defkey org-mode-map [?\C-c (right)] 'org-shiftright)
+ (org-defkey org-mode-map [?\C-c ?\C-x (right)] 'org-shiftcontrolright)
+ (org-defkey org-mode-map [?\C-c ?\C-x (left)] 'org-shiftcontrolleft))
;; All the other keys
-(define-key org-mode-map "\C-c\C-a" 'show-all) ; in case allout messed up.
-(define-key org-mode-map "\C-c\C-r" 'org-reveal)
-(define-key org-mode-map "\C-xns" 'org-narrow-to-subtree)
-(define-key org-mode-map "\C-c$" 'org-archive-subtree)
-(define-key org-mode-map "\C-c\C-x\C-s" 'org-advertized-archive-subtree)
-(define-key org-mode-map "\C-c\C-x\C-a" 'org-toggle-archive-tag)
-(define-key org-mode-map "\C-c\C-xb" 'org-tree-to-indirect-buffer)
-(define-key org-mode-map "\C-c\C-j" 'org-goto)
-(define-key org-mode-map "\C-c\C-t" 'org-todo)
-(define-key org-mode-map "\C-c\C-s" 'org-schedule)
-(define-key org-mode-map "\C-c\C-d" 'org-deadline)
-(define-key org-mode-map "\C-c;" 'org-toggle-comment)
-(define-key org-mode-map "\C-c\C-v" 'org-show-todo-tree)
-(define-key org-mode-map "\C-c\C-w" 'org-check-deadlines)
-(define-key org-mode-map "\C-c/" 'org-occur) ; Minor-mode reserved
-(define-key org-mode-map "\C-c\\" 'org-tags-sparse-tree) ; Minor-mode res.
-(define-key org-mode-map "\C-c\C-m" 'org-insert-heading)
-(define-key org-mode-map "\M-\C-m" 'org-insert-heading)
-(define-key org-mode-map "\C-c\C-x\C-n" 'org-next-link)
-(define-key org-mode-map "\C-c\C-x\C-p" 'org-previous-link)
-(define-key org-mode-map "\C-c\C-l" 'org-insert-link)
-(define-key org-mode-map "\C-c\C-o" 'org-open-at-point)
-(define-key org-mode-map "\C-c%" 'org-mark-ring-push)
-(define-key org-mode-map "\C-c&" 'org-mark-ring-goto)
-(define-key org-mode-map "\C-c\C-z" 'org-time-stamp) ; Alternative binding
-(define-key org-mode-map "\C-c." 'org-time-stamp) ; Minor-mode reserved
-(define-key org-mode-map "\C-c!" 'org-time-stamp-inactive) ; Minor-mode r.
-(define-key org-mode-map "\C-c," 'org-priority) ; Minor-mode reserved
-(define-key org-mode-map "\C-c\C-y" 'org-evaluate-time-range)
-(define-key org-mode-map "\C-c>" 'org-goto-calendar)
-(define-key org-mode-map "\C-c<" 'org-date-from-calendar)
-(define-key org-mode-map [(control ?,)] 'org-cycle-agenda-files)
-(define-key org-mode-map [(control ?\')] 'org-cycle-agenda-files)
-(define-key org-mode-map "\C-c[" 'org-agenda-file-to-front)
-(define-key org-mode-map "\C-c]" 'org-remove-file)
-(define-key org-mode-map "\C-c-" 'org-table-insert-hline)
-(define-key org-mode-map "\C-c^" 'org-sort)
-(define-key org-mode-map "\C-c\C-c" 'org-ctrl-c-ctrl-c)
-(define-key org-mode-map "\C-c#" 'org-update-checkbox-count)
-(define-key org-mode-map "\C-m" 'org-return)
-(define-key org-mode-map "\C-c?" 'org-table-field-info)
-(define-key org-mode-map "\C-c " 'org-table-blank-field)
-(define-key org-mode-map "\C-c+" 'org-table-sum)
-(define-key org-mode-map "\C-c=" 'org-table-eval-formula)
-(define-key org-mode-map "\C-c'" 'org-table-edit-formulas)
-(define-key org-mode-map "\C-c`" 'org-table-edit-field)
-(define-key org-mode-map "\C-c|" 'org-table-create-or-convert-from-region)
-(define-key org-mode-map "\C-c*" 'org-table-recalculate)
-(define-key org-mode-map [(control ?#)] 'org-table-rotate-recalc-marks)
-(define-key org-mode-map "\C-c~" 'org-table-create-with-table.el)
-(define-key org-mode-map "\C-c\C-q" 'org-table-wrap-region)
-(define-key org-mode-map "\C-c}" 'org-table-toggle-coordinate-overlays)
-(define-key org-mode-map "\C-c{" 'org-table-toggle-formula-debugger)
-(define-key org-mode-map "\C-c\C-e" 'org-export)
-(define-key org-mode-map "\C-c:" 'org-toggle-fixed-width-section)
-
-(define-key org-mode-map "\C-c\C-x\C-k" 'org-cut-special)
-(define-key org-mode-map "\C-c\C-x\C-w" 'org-cut-special)
-(define-key org-mode-map "\C-c\C-x\M-w" 'org-copy-special)
-(define-key org-mode-map "\C-c\C-x\C-y" 'org-paste-special)
-
-(define-key org-mode-map "\C-c\C-x\C-t" 'org-toggle-time-stamp-overlays)
-(define-key org-mode-map "\C-c\C-x\C-i" 'org-clock-in)
-(define-key org-mode-map "\C-c\C-x\C-o" 'org-clock-out)
-(define-key org-mode-map "\C-c\C-x\C-x" 'org-clock-cancel)
-(define-key org-mode-map "\C-c\C-x\C-d" 'org-clock-display)
-(define-key org-mode-map "\C-c\C-x\C-r" 'org-clock-report)
-(define-key org-mode-map "\C-c\C-x\C-u" 'org-dblock-update)
-(define-key org-mode-map "\C-c\C-x\C-l" 'org-preview-latex-fragment)
-(define-key org-mode-map "\C-c\C-x\C-b" 'org-toggle-checkbox)
+(org-defkey org-mode-map "\C-c\C-a" 'show-all) ; in case allout messed up.
+(org-defkey org-mode-map "\C-c\C-r" 'org-reveal)
+(org-defkey org-mode-map "\C-xns" 'org-narrow-to-subtree)
+(org-defkey org-mode-map "\C-c$" 'org-archive-subtree)
+(org-defkey org-mode-map "\C-c\C-x\C-s" 'org-advertized-archive-subtree)
+(org-defkey org-mode-map "\C-c\C-x\C-a" 'org-toggle-archive-tag)
+(org-defkey org-mode-map "\C-c\C-xb" 'org-tree-to-indirect-buffer)
+(org-defkey org-mode-map "\C-c\C-j" 'org-goto)
+(org-defkey org-mode-map "\C-c\C-t" 'org-todo)
+(org-defkey org-mode-map "\C-c\C-s" 'org-schedule)
+(org-defkey org-mode-map "\C-c\C-d" 'org-deadline)
+(org-defkey org-mode-map "\C-c;" 'org-toggle-comment)
+(org-defkey org-mode-map "\C-c\C-v" 'org-show-todo-tree)
+(org-defkey org-mode-map "\C-c\C-w" 'org-refile)
+(org-defkey org-mode-map "\C-c/" 'org-sparse-tree) ; Minor-mode reserved
+(org-defkey org-mode-map "\C-c\\" 'org-tags-sparse-tree) ; Minor-mode res.
+(org-defkey org-mode-map "\C-c\C-m" 'org-ctrl-c-ret)
+(org-defkey org-mode-map "\M-\C-m" 'org-insert-heading)
+(org-defkey org-mode-map [(control return)] 'org-insert-heading-after-current)
+(org-defkey org-mode-map "\C-c\C-x\C-n" 'org-next-link)
+(org-defkey org-mode-map "\C-c\C-x\C-p" 'org-previous-link)
+(org-defkey org-mode-map "\C-c\C-l" 'org-insert-link)
+(org-defkey org-mode-map "\C-c\C-o" 'org-open-at-point)
+(org-defkey org-mode-map "\C-c%" 'org-mark-ring-push)
+(org-defkey org-mode-map "\C-c&" 'org-mark-ring-goto)
+(org-defkey org-mode-map "\C-c\C-z" 'org-time-stamp) ; Alternative binding
+(org-defkey org-mode-map "\C-c." 'org-time-stamp) ; Minor-mode reserved
+(org-defkey org-mode-map "\C-c!" 'org-time-stamp-inactive) ; Minor-mode r.
+(org-defkey org-mode-map "\C-c," 'org-priority) ; Minor-mode reserved
+(org-defkey org-mode-map "\C-c\C-y" 'org-evaluate-time-range)
+(org-defkey org-mode-map "\C-c>" 'org-goto-calendar)
+(org-defkey org-mode-map "\C-c<" 'org-date-from-calendar)
+(org-defkey org-mode-map [(control ?,)] 'org-cycle-agenda-files)
+(org-defkey org-mode-map [(control ?\')] 'org-cycle-agenda-files)
+(org-defkey org-mode-map "\C-c[" 'org-agenda-file-to-front)
+(org-defkey org-mode-map "\C-c]" 'org-remove-file)
+(org-defkey org-mode-map "\C-c\C-x<" 'org-agenda-set-restriction-lock)
+(org-defkey org-mode-map "\C-c\C-x>" 'org-agenda-remove-restriction-lock)
+(org-defkey org-mode-map "\C-c-" 'org-ctrl-c-minus)
+(org-defkey org-mode-map "\C-c*" 'org-ctrl-c-star)
+(org-defkey org-mode-map "\C-c^" 'org-sort)
+(org-defkey org-mode-map "\C-c\C-c" 'org-ctrl-c-ctrl-c)
+(org-defkey org-mode-map "\C-c\C-k" 'org-kill-note-or-show-branches)
+(org-defkey org-mode-map "\C-c#" 'org-update-checkbox-count)
+(org-defkey org-mode-map "\C-m" 'org-return)
+(org-defkey org-mode-map "\C-j" 'org-return-indent)
+(org-defkey org-mode-map "\C-c?" 'org-table-field-info)
+(org-defkey org-mode-map "\C-c " 'org-table-blank-field)
+(org-defkey org-mode-map "\C-c+" 'org-table-sum)
+(org-defkey org-mode-map "\C-c=" 'org-table-eval-formula)
+(org-defkey org-mode-map "\C-c'" 'org-table-edit-formulas)
+(org-defkey org-mode-map "\C-c`" 'org-table-edit-field)
+(org-defkey org-mode-map "\C-c|" 'org-table-create-or-convert-from-region)
+(org-defkey org-mode-map [(control ?#)] 'org-table-rotate-recalc-marks)
+(org-defkey org-mode-map "\C-c~" 'org-table-create-with-table.el)
+(org-defkey org-mode-map "\C-c\C-q" 'org-table-wrap-region)
+(org-defkey org-mode-map "\C-c}" 'org-table-toggle-coordinate-overlays)
+(org-defkey org-mode-map "\C-c{" 'org-table-toggle-formula-debugger)
+(org-defkey org-mode-map "\C-c\C-e" 'org-export)
+(org-defkey org-mode-map "\C-c:" 'org-toggle-fixed-width-section)
+(org-defkey org-mode-map "\C-c\C-x\C-f" 'org-emphasize)
+
+(org-defkey org-mode-map "\C-c\C-x\C-k" 'org-cut-special)
+(org-defkey org-mode-map "\C-c\C-x\C-w" 'org-cut-special)
+(org-defkey org-mode-map "\C-c\C-x\M-w" 'org-copy-special)
+(org-defkey org-mode-map "\C-c\C-x\C-y" 'org-paste-special)
+
+(org-defkey org-mode-map "\C-c\C-x\C-t" 'org-toggle-time-stamp-overlays)
+(org-defkey org-mode-map "\C-c\C-x\C-i" 'org-clock-in)
+(org-defkey org-mode-map "\C-c\C-x\C-o" 'org-clock-out)
+(org-defkey org-mode-map "\C-c\C-x\C-j" 'org-clock-goto)
+(org-defkey org-mode-map "\C-c\C-x\C-x" 'org-clock-cancel)
+(org-defkey org-mode-map "\C-c\C-x\C-d" 'org-clock-display)
+(org-defkey org-mode-map "\C-c\C-x\C-r" 'org-clock-report)
+(org-defkey org-mode-map "\C-c\C-x\C-u" 'org-dblock-update)
+(org-defkey org-mode-map "\C-c\C-x\C-l" 'org-preview-latex-fragment)
+(org-defkey org-mode-map "\C-c\C-x\C-b" 'org-toggle-checkbox)
+(org-defkey org-mode-map "\C-c\C-xp" 'org-set-property)
+(org-defkey org-mode-map "\C-c\C-xr" 'org-insert-columns-dblock)
+
+(define-key org-mode-map "\C-c\C-x\C-c" 'org-columns)
(when (featurep 'xemacs)
- (define-key org-mode-map 'button3 'popup-mode-menu))
+ (org-defkey org-mode-map 'button3 'popup-mode-menu))
(defsubst org-table-p () (org-at-table-p))
(goto-char (match-beginning 0))
(self-insert-command N))
(setq org-table-may-need-update t)
- (self-insert-command N)))
+ (self-insert-command N)
+ (org-fix-tags-on-the-fly)))
+
+(defun org-fix-tags-on-the-fly ()
+ (when (and (equal (char-after (point-at-bol)) ?*)
+ (org-on-heading-p))
+ (org-align-tags-here org-tags-column)))
(defun org-delete-backward-char (N)
"Like `delete-backward-char', insert whitespace at field end in tables.
;; noalign: if there were two spaces at the end, this field
;; does not determine the width of the column.
(if noalign (setq org-table-may-need-update c)))
- (backward-delete-char N)))
+ (backward-delete-char N)
+ (org-fix-tags-on-the-fly)))
(defun org-delete-char (N)
"Like `delete-char', but insert whitespace at field end in tables.
;; does not determine the width of the column.
(if noalign (setq org-table-may-need-update c)))
(delete-char N))
- (delete-char N)))
+ (delete-char N)
+ (org-fix-tags-on-the-fly)))
;; Make `delete-selection-mode' work with org-mode and orgtbl-mode
(put 'org-self-insert-command 'delete-selection t)
(put 'org-delete-char 'flyspell-delayed t)
(put 'org-delete-backward-char 'flyspell-delayed t)
+;; Make pabbrev-mode expand after org-mode commands
+(put 'org-self-insert-command 'pabbrev-expand-after-command t)
+(put 'orgybl-self-insert-command 'pabbrev-expand-after-command t)
;; How to do this: Measure non-white length of current string
;; If equal to column width, we should realign.
(while commands
(setq old (pop commands) new (pop commands))
(if (fboundp 'command-remapping)
- (define-key map (vector 'remap old) new)
+ (org-defkey map (vector 'remap old) new)
(substitute-key-definition old new map global-map)))))
(when (eq org-enable-table-editor 'optimized)
'self-insert-command 'org-self-insert-command
'delete-char 'org-delete-char
'delete-backward-char 'org-delete-backward-char)
- (define-key org-mode-map "|" 'org-force-self-insert))
+ (org-defkey org-mode-map "|" 'org-force-self-insert))
(defun org-shiftcursor-error ()
"Throw an error because Shift-Cursor command was applied in wrong context."
(defun org-shiftmetaleft ()
"Promote subtree or delete table column.
-Calls `org-promote-subtree' or `org-table-delete-column', depending on context.
+Calls `org-promote-subtree', `org-outdent-item',
+or `org-table-delete-column', depending on context.
See the individual commands for more information."
(interactive)
(cond
(defun org-shiftmetaright ()
"Demote subtree or insert table column.
-Calls `org-demote-subtree' or `org-table-insert-column', depending on context.
+Calls `org-demote-subtree', `org-indent-item',
+or `org-table-insert-column', depending on context.
See the individual commands for more information."
(interactive)
(cond
((org-at-table-p) (org-call-with-arg 'org-table-move-row 'up))
((org-on-heading-p) (call-interactively 'org-move-subtree-up))
((org-at-item-p) (call-interactively 'org-move-item-up))
- (t (org-shiftcursor-error))))
+ (t (transpose-lines 1) (beginning-of-line -1))))
(defun org-metadown (&optional arg)
"Move subtree down or move table row down.
((org-at-table-p) (call-interactively 'org-table-move-row))
((org-on-heading-p) (call-interactively 'org-move-subtree-down))
((org-at-item-p) (call-interactively 'org-move-item-down))
- (t (org-shiftcursor-error))))
+ (t (beginning-of-line 2) (transpose-lines 1) (beginning-of-line 0))))
(defun org-shiftup (&optional arg)
"Increase item in timestamp or increase priority of current headline.
-Calls `org-timestamp-up' or `org-priority-up', depending on context.
-See the individual commands for more information."
+Calls `org-timestamp-up' or `org-priority-up', or `org-previous-item',
+depending on context. See the individual commands for more information."
(interactive "P")
(cond
- ((org-at-timestamp-p t) (call-interactively 'org-timestamp-up))
+ ((org-at-timestamp-p t)
+ (call-interactively (if org-edit-timestamp-down-means-later
+ 'org-timestamp-down 'org-timestamp-up)))
((org-on-heading-p) (call-interactively 'org-priority-up))
((org-at-item-p) (call-interactively 'org-previous-item))
(t (call-interactively 'org-beginning-of-item) (beginning-of-line 1))))
(defun org-shiftdown (&optional arg)
"Decrease item in timestamp or decrease priority of current headline.
-Calls `org-timestamp-down' or `org-priority-down', depending on context.
-See the individual commands for more information."
+Calls `org-timestamp-down' or `org-priority-down', or `org-next-item'
+depending on context. See the individual commands for more information."
(interactive "P")
(cond
- ((org-at-timestamp-p t) (call-interactively 'org-timestamp-down))
+ ((org-at-timestamp-p t)
+ (call-interactively (if org-edit-timestamp-down-means-later
+ 'org-timestamp-up 'org-timestamp-down)))
((org-on-heading-p) (call-interactively 'org-priority-down))
(t (call-interactively 'org-next-item))))
(cond
((org-at-timestamp-p t) (call-interactively 'org-timestamp-up-day))
((org-on-heading-p) (org-call-with-arg 'org-todo 'right))
+ ((org-at-item-p) (org-call-with-arg 'org-cycle-list-bullet nil))
+ ((org-at-property-p) (call-interactively 'org-property-next-allowed-value))
(t (org-shiftcursor-error))))
(defun org-shiftleft ()
(cond
((org-at-timestamp-p t) (call-interactively 'org-timestamp-down-day))
((org-on-heading-p) (org-call-with-arg 'org-todo 'left))
+ ((org-at-item-p) (org-call-with-arg 'org-cycle-list-bullet 'previous))
+ ((org-at-property-p)
+ (call-interactively 'org-property-previous-allowed-value))
+ (t (org-shiftcursor-error))))
+
+(defun org-shiftcontrolright ()
+ "Switch to next TODO set."
+ (interactive)
+ (cond
+ ((org-on-heading-p) (org-call-with-arg 'org-todo 'nextset))
+ (t (org-shiftcursor-error))))
+
+(defun org-shiftcontrolleft ()
+ "Switch to previous TODO set."
+ (interactive)
+ (cond
+ ((org-on-heading-p) (org-call-with-arg 'org-todo 'previousset))
(t (org-shiftcursor-error))))
+(defun org-ctrl-c-ret ()
+ "Call `org-table-hline-and-move' or `org-insert-heading' dep. on context."
+ (interactive)
+ (cond
+ ((org-at-table-p) (call-interactively 'org-table-hline-and-move))
+ (t (call-interactively 'org-insert-heading))))
+
(defun org-copy-special ()
"Copy region in table or copy current subtree.
Calls `org-table-copy' or `org-copy-subtree', depending on context.
- If the cursor is on a #+TBLFM line, re-apply the formulas to
the entire table.
+- If the cursor is a the beginning of a dynamic block, update it.
+
- If the cursor is inside a table created by the table.el package,
activate that table.
links in this buffer.
- If the cursor is on a numbered item in a plain list, renumber the
- ordered list."
+ ordered list.
+
+- If the cursor is on a checkbox, toggle it."
(interactive "P")
(let ((org-enable-table-editor t))
(cond
((and (local-variable-p 'org-finish-function (current-buffer))
(fboundp org-finish-function))
(funcall org-finish-function))
+ ((org-at-property-p)
+ (call-interactively 'org-property-action))
((org-on-target-p) (call-interactively 'org-update-radio-target-regexp))
((org-on-heading-p) (call-interactively 'org-set-tags))
((org-at-table.el-p)
((org-at-item-checkbox-p)
(call-interactively 'org-toggle-checkbox))
((org-at-item-p)
- (call-interactively 'org-renumber-ordered-list))
+ (call-interactively 'org-maybe-renumber-ordered-list))
+ ((save-excursion (beginning-of-line 1) (looking-at "#\\+BEGIN:"))
+ ;; Dynamic block
+ (beginning-of-line 1)
+ (org-update-dblock))
((save-excursion (beginning-of-line 1) (looking-at "#\\+\\([A-Z]+\\)"))
(cond
((equal (match-string 1) "TBLFM")
(let ((org-inhibit-startup t)) (org-mode))
(message "Org-mode restarted to refresh keyword and special line setup"))
-(defun org-return ()
+(defun org-kill-note-or-show-branches ()
+ "If this is a Note buffer, abort storing the note. Else call `show-branches'."
+ (interactive)
+ (if (not org-finish-function)
+ (call-interactively 'show-branches)
+ (let ((org-note-abort t))
+ (funcall org-finish-function))))
+
+(defun org-return (&optional indent)
"Goto next table row or insert a newline.
Calls `org-table-next-row' or `newline', depending on context.
See the individual commands for more information."
(interactive)
(cond
+ ((bobp) (if indent (newline-and-indent) (newline)))
+ ((and (org-at-heading-p)
+ (looking-at
+ (org-re "\\([ \t]+\\(:[[:alnum:]_@:]+:\\)\\)[ \t]*$")))
+ (org-show-entry)
+ (end-of-line 1)
+ (newline))
((org-at-table-p)
(org-table-justify-field-maybe)
(call-interactively 'org-table-next-row))
- (t (newline))))
+ (t (if indent (newline-and-indent) (newline)))))
+
+(defun org-return-indent ()
+ "Goto next table row or insert a newline and indent.
+Calls `org-table-next-row' or `newline-and-indent', depending on
+context. See the individual commands for more information."
+ (interactive)
+ (org-return t))
+
+(defun org-ctrl-c-star ()
+ "Compute table, or change heading status of lines.
+Calls `org-table-recalculate' or `org-toggle-region-headlines',
+depending on context. This will also turn a plain list item or a normal
+line into a subheading."
+ (interactive)
+ (cond
+ ((org-at-table-p)
+ (call-interactively 'org-table-recalculate))
+ ((org-region-active-p)
+ ;; Convert all lines in region to list items
+ (call-interactively 'org-toggle-region-headings))
+ ((org-on-heading-p)
+ (org-toggle-region-headings (point-at-bol)
+ (min (1+ (point-at-eol)) (point-max))))
+ ((org-at-item-p)
+ ;; Convert to heading
+ (let ((level (save-match-data
+ (save-excursion
+ (condition-case nil
+ (progn
+ (org-back-to-heading t)
+ (funcall outline-level))
+ (error 0))))))
+ (replace-match
+ (concat (make-string (org-get-valid-level level 1) ?*) " ") t t)))
+ (t (org-toggle-region-headings (point-at-bol)
+ (min (1+ (point-at-eol)) (point-max))))))
+
+(defun org-ctrl-c-minus ()
+ "Insert separator line in table or modify bullet status of line.
+Also turns a plain line or a region of lines into list items.
+Calls `org-table-insert-hline', `org-toggle-region-items', or
+`org-cycle-list-bullet', depending on context."
+ (interactive)
+ (cond
+ ((org-at-table-p)
+ (call-interactively 'org-table-insert-hline))
+ ((org-on-heading-p)
+ ;; Convert to item
+ (save-excursion
+ (beginning-of-line 1)
+ (if (looking-at "\\*+ ")
+ (replace-match (concat (make-string (- (match-end 0) (point) 1) ?\ ) "- ")))))
+ ((org-region-active-p)
+ ;; Convert all lines in region to list items
+ (call-interactively 'org-toggle-region-items))
+ ((org-in-item-p)
+ (call-interactively 'org-cycle-list-bullet))
+ (t (org-toggle-region-items (point-at-bol)
+ (min (1+ (point-at-eol)) (point-max))))))
+
+(defun org-toggle-region-items (beg end)
+ "Convert all lines in region to list items.
+If the first line is already an item, convert all list items in the region
+to normal lines."
+ (interactive "r")
+ (let (l2 l)
+ (save-excursion
+ (goto-char end)
+ (setq l2 (org-current-line))
+ (goto-char beg)
+ (beginning-of-line 1)
+ (setq l (1- (org-current-line)))
+ (if (org-at-item-p)
+ ;; We already have items, de-itemize
+ (while (< (setq l (1+ l)) l2)
+ (when (org-at-item-p)
+ (goto-char (match-beginning 2))
+ (delete-region (match-beginning 2) (match-end 2))
+ (and (looking-at "[ \t]+") (replace-match "")))
+ (beginning-of-line 2))
+ (while (< (setq l (1+ l)) l2)
+ (unless (org-at-item-p)
+ (if (looking-at "\\([ \t]*\\)\\(\\S-\\)")
+ (replace-match "\\1- \\2")))
+ (beginning-of-line 2))))))
+
+(defun org-toggle-region-headings (beg end)
+ "Convert all lines in region to list items.
+If the first line is already an item, convert all list items in the region
+to normal lines."
+ (interactive "r")
+ (let (l2 l)
+ (save-excursion
+ (goto-char end)
+ (setq l2 (org-current-line))
+ (goto-char beg)
+ (beginning-of-line 1)
+ (setq l (1- (org-current-line)))
+ (if (org-on-heading-p)
+ ;; We already have headlines, de-star them
+ (while (< (setq l (1+ l)) l2)
+ (when (org-on-heading-p t)
+ (and (looking-at outline-regexp) (replace-match "")))
+ (beginning-of-line 2))
+ (let* ((stars (save-excursion
+ (re-search-backward org-complex-heading-regexp nil t)
+ (or (match-string 1) "*")))
+ (add-stars (if org-odd-levels-only "**" "*"))
+ (rpl (concat stars add-stars " \\2")))
+ (while (< (setq l (1+ l)) l2)
+ (unless (org-on-heading-p)
+ (if (looking-at "\\([ \t]*\\)\\(\\S-\\)")
+ (replace-match rpl)))
+ (beginning-of-line 2)))))))
(defun org-meta-return (&optional arg)
"Insert a new heading or wrap a region in a table.
["Insert Row" org-shiftmetadown (org-at-table-p)]
["Sort lines in region" org-table-sort-lines (org-at-table-p)]
"--"
- ["Insert Hline" org-table-insert-hline (org-at-table-p)])
+ ["Insert Hline" org-ctrl-c-minus (org-at-table-p)])
("Rectangle"
["Copy Rectangle" org-copy-special (org-at-table-p)]
["Cut Rectangle" org-cut-special (org-at-table-p)]
"--"
["Convert to odd levels" org-convert-to-odd-levels t]
["Convert to odd/even levels" org-convert-to-oddeven-levels t])
+ ("Editing"
+ ["Emphasis..." org-emphasize t])
("Archive"
["Toggle ARCHIVE tag" org-toggle-archive-tag t]
; ["Check and Tag Children" (org-toggle-archive-tag (4))
("Select keyword"
["Next keyword" org-shiftright (org-on-heading-p)]
["Previous keyword" org-shiftleft (org-on-heading-p)]
- ["Complete Keyword" org-complete (assq :todo-keyword (org-context))])
+ ["Complete Keyword" org-complete (assq :todo-keyword (org-context))]
+ ["Next keyword set" org-shiftcontrolright (and (> (length org-todo-sets) 1) (org-on-heading-p))]
+ ["Previous keyword set" org-shiftcontrolright (and (> (length org-todo-sets) 1) (org-on-heading-p))])
["Show TODO Tree" org-show-todo-tree t]
["Global TODO list" org-todo-list t]
"--"
["Set Priority" org-priority t]
["Priority Up" org-shiftup t]
- ["Priority Down" org-shiftdown t]
+ ["Priority Down" org-shiftdown t])
+ ("TAGS and Properties"
+ ["Set Tags" 'org-ctrl-c-ctrl-c (org-at-heading-p)]
+ ["Change tag in region" 'org-change-tag-in-region (org-region-active-p)]
"--"
-; ["Insert Checkbox" org-insert-todo-heading (org-in-item-p)]
-; ["Toggle Checkbox" org-ctrl-c-ctrl-c (org-at-item-checkbox-p)]
-; ["Insert [n/m] cookie" (progn (insert "[/]") (org-update-checkbox-count))
-; (or (org-on-heading-p) (org-at-item-p))]
-; ["Insert [%] cookie" (progn (insert "[%]") (org-update-checkbox-count))
-; (or (org-on-heading-p) (org-at-item-p))]
-; ["Update Statistics" org-update-checkbox-count t]
- )
+ ["Set property" 'org-set-property t]
+ ["Column view of properties" org-columns t]
+ ["Insert Column View DBlock" org-insert-columns-dblock t])
("Dates and Scheduling"
["Timestamp" org-time-stamp t]
["Timestamp (inactive)" org-time-stamp-inactive t]
["Clock in" org-clock-in t]
["Clock out" org-clock-out t]
["Clock cancel" org-clock-cancel t]
+ ["Goto running clock" org-clock-goto t]
["Display times" org-clock-display t]
["Create clock table" org-clock-report t]
"--"
["Record DONE time"
(progn (setq org-log-done (not org-log-done))
(message "Switching to %s will %s record a timestamp"
- org-done-string
+ (car org-done-keywords)
(if org-log-done "automatically" "not")))
:style toggle :selected org-log-done])
"--"
["Agenda Command..." org-agenda t]
+ ["Set Restriction Lock" org-agenda-set-restriction-lock t]
("File List for Agenda")
("Special views current file"
["TODO Tree" org-show-todo-tree t]
["Refresh setup" org-mode-restart t]
))
-(defun org-toggle-log-option (type)
- (if (not (listp org-log-done)) (setq org-log-done nil))
- (if (memq type org-log-done)
- (setq org-log-done (delq type org-log-done))
- (add-to-list 'org-log-done type)))
-
-(defun org-check-log-option (type)
- (and (listp org-log-done) (memq type org-log-done)))
-
(defun org-info (&optional node)
"Read documentation for Org-mode in the info system.
With optional NODE, go directly to that node."
(interactive)
- (require 'info)
- (Info-goto-node (format "(org)%s" (or node ""))))
+ (info (format "(org)%s" (or node ""))))
(defun org-install-agenda-files-menu ()
(let ((bl (buffer-list)))
["Add/Move Current File to Front of List" org-agenda-file-to-front t]
["Remove Current File from List" org-remove-file t]
["Cycle through agenda files" org-cycle-agenda-files t]
+ ["Occur in all agenda files" org-occur-in-agenda-files t]
"--")
(mapcar 'org-file-menu-entry (org-agenda-files t))))))))
(p (point)) clist o)
;; First the large context
(cond
- ((org-on-heading-p)
+ ((org-on-heading-p t)
(push (list :headline (point-at-bol) (point-at-eol)) clist)
(when (progn
(beginning-of-line 1)
(push (org-point-in-group p 4 :tags) clist))
(goto-char p)
(skip-chars-backward "^[\n\r \t") (or (eobp) (backward-char 1))
- (if (looking-at "\\[#[A-Z]\\]")
+ (if (looking-at "\\[#[A-Z0-9]\\]")
(push (org-point-in-group p 0 :priority) clist)))
((org-at-item-p)
(setq clist (nreverse (delq nil clist)))
clist))
+;; FIXME: Compare with at-regexp-p Do we need both?
(defun org-in-regexp (re &optional nlines visually)
"Check if point is inside a match of regexp.
Normally only the current line is checked, but you can include NLINES extra
(>= (+ inc (match-end 0)) pos))
(throw 'exit (cons (match-beginning 0) (match-end 0)))))))))
+(defun org-at-regexp-p (regexp)
+ "Is point inside a match of REGEXP in the current line?"
+ (catch 'exit
+ (save-excursion
+ (let ((pos (point)) (end (point-at-eol)))
+ (beginning-of-line 1)
+ (while (re-search-forward regexp end t)
+ (if (and (<= (match-beginning 0) pos)
+ (>= (match-end 0) pos))
+ (throw 'exit t)))
+ nil))))
+
+(defun org-occur-in-agenda-files (regexp &optional nlines)
+ "Call `multi-occur' with buffers for all agenda files."
+ (interactive "sOrg-files matching: \np")
+ (let* ((files (org-agenda-files))
+ (tnames (mapcar 'file-truename files))
+ (extra org-agenda-text-search-extra-files)
+ f)
+ (while (setq f (pop extra))
+ (unless (member (file-truename f) tnames)
+ (add-to-list 'files f 'append)
+ (add-to-list 'tnames (file-truename f) 'append)))
+ (multi-occur
+ (mapcar (lambda (x) (or (get-file-buffer x) (find-file-noselect x))) files)
+ regexp)))
+
+(if (boundp 'occur-mode-find-occurrence-hook)
+ ;; Emacs 23
+ (add-hook 'occur-mode-find-occurrence-hook
+ (lambda ()
+ (when (org-mode-p)
+ (org-reveal))))
+ ;; Emacs 22
+ (defadvice occur-mode-goto-occurrence
+ (after org-occur-reveal activate)
+ (and (org-mode-p) (org-reveal)))
+ (defadvice occur-mode-goto-occurrence-other-window
+ (after org-occur-reveal activate)
+ (and (org-mode-p) (org-reveal)))
+ (defadvice occur-mode-display-occurrence
+ (after org-occur-reveal activate)
+ (when (org-mode-p)
+ (let ((pos (occur-mode-find-occurrence)))
+ (with-current-buffer (marker-buffer pos)
+ (save-excursion
+ (goto-char pos)
+ (org-reveal)))))))
+
+(defun org-uniquify (list)
+ "Remove duplicate elements from LIST."
+ (let (res)
+ (mapc (lambda (x) (add-to-list 'res x 'append)) list)
+ res))
+
+(defun org-delete-all (elts list)
+ "Remove all elements in ELTS from LIST."
+ (while elts
+ (setq list (delete (pop elts) list)))
+ list)
+
+(defun org-back-over-empty-lines ()
+ "Move backwards over witespace, to the beginning of the first empty line.
+Returns the number of empty lines passed."
+ (let ((pos (point)))
+ (skip-chars-backward " \t\n\r")
+ (beginning-of-line 2)
+ (goto-char (min (point) pos))
+ (count-lines (point) pos)))
+
+(defun org-skip-whitespace ()
+ (skip-chars-forward " \t\n\r"))
+
(defun org-point-in-group (point group &optional context)
"Check if POINT is in match-group GROUP.
If CONTEXT is non-nil, return a list with CONTEXT and the boundaries of the
(list context (match-beginning group) (match-end group))
t)))
+(defun org-switch-to-buffer-other-window (&rest args)
+ "Switch to buffer in a second window on the current frame.
+In particular, do not allow pop-up frames."
+ (let (pop-up-frames special-display-buffer-names special-display-regexps
+ special-display-function)
+ (apply 'switch-to-buffer-other-window args)))
+
(defun org-combine-plists (&rest plists)
"Create a single property list from all plists in PLISTS.
The process starts by copying the first list, and then setting properties
(defun org-replace-escapes (string table)
"Replace %-escapes in STRING with values in TABLE.
-TABLE is an association list with keys line \"%a\" and string values.
+TABLE is an association list with keys like \"%a\" and string values.
The sequences in STRING may contain normal field width and padding information,
for example \"%-5s\". Replacements happen in the sequence given by TABLE,
so values can contain further %-escapes if they are define later in TABLE."
(setq c (1+ c)))
(nreverse rtn)))
-(defun org-at-regexp-p (regexp)
- "Is point inside a match of REGEXP in the current line?"
- (catch 'exit
- (save-excursion
- (let ((pos (point)) (end (point-at-eol)))
- (beginning-of-line 1)
- (while (re-search-forward regexp end t)
- (if (and (<= (match-beginning 0) pos)
- (>= (match-end 0) pos))
- (throw 'exit t)))
- nil))))
-
(defun org-find-base-buffer-visiting (file)
"Like `find-buffer-visiting' but alway return the base buffer and
-not an indirect buffer"
+not an indirect buffer."
(let ((buf (find-buffer-visiting file)))
- (or (buffer-base-buffer buf) buf)))
+ (if buf
+ (or (buffer-base-buffer buf) buf)
+ nil)))
+
+(defun org-image-file-name-regexp ()
+ "Return regexp matching the file names of images."
+ (if (fboundp 'image-file-name-regexp)
+ (image-file-name-regexp)
+ (let ((image-file-name-extensions
+ '("png" "jpeg" "jpg" "gif" "tiff" "tif"
+ "xbm" "xpm" "pbm" "pgm" "ppm")))
+ (concat "\\."
+ (regexp-opt (nconc (mapcar 'upcase
+ image-file-name-extensions)
+ image-file-name-extensions)
+ t)
+ "\\'"))))
+
+(defun org-file-image-p (file)
+ "Return non-nil if FILE is an image."
+ (save-match-data
+ (string-match (org-image-file-name-regexp) file)))
;;; Paragraph filling stuff.
;; We want this to be just right, so use the full arsenal.
-;; FIXME: configure filladapt for XEmacs
+
+(defun org-indent-line-function ()
+ "Indent line like previous, but further if previous was headline or item."
+ (interactive)
+ (let* ((pos (point))
+ (itemp (org-at-item-p))
+ column bpos bcol tpos tcol bullet btype bullet-type)
+ ;; Find the previous relevant line
+ (beginning-of-line 1)
+ (cond
+ ((looking-at "#") (setq column 0))
+ ((looking-at "\\*+ ") (setq column 0))
+ (t
+ (beginning-of-line 0)
+ (while (and (not (bobp)) (looking-at "[ \t]*[\n:#|]"))
+ (beginning-of-line 0))
+ (cond
+ ((looking-at "\\*+[ \t]+")
+ (goto-char (match-end 0))
+ (setq column (current-column)))
+ ((org-in-item-p)
+ (org-beginning-of-item)
+; (looking-at "[ \t]*\\(\\S-+\\)[ \t]*")
+ (looking-at "[ \t]*\\(\\S-+\\)[ \t]*\\(\\[[- X]\\][ \t]*\\)?")
+ (setq bpos (match-beginning 1) tpos (match-end 0)
+ bcol (progn (goto-char bpos) (current-column))
+ tcol (progn (goto-char tpos) (current-column))
+ bullet (match-string 1)
+ bullet-type (if (string-match "[0-9]" bullet) "n" bullet))
+ (if (not itemp)
+ (setq column tcol)
+ (goto-char pos)
+ (beginning-of-line 1)
+ (if (looking-at "\\S-")
+ (progn
+ (looking-at "[ \t]*\\(\\S-+\\)[ \t]*")
+ (setq bullet (match-string 1)
+ btype (if (string-match "[0-9]" bullet) "n" bullet))
+ (setq column (if (equal btype bullet-type) bcol tcol)))
+ (setq column (org-get-indentation)))))
+ (t (setq column (org-get-indentation))))))
+ (goto-char pos)
+ (if (<= (current-column) (current-indentation))
+ (indent-line-to column)
+ (save-excursion (indent-line-to column)))
+ (setq column (current-column))
+ (beginning-of-line 1)
+ (if (looking-at
+ "\\([ \t]+\\)\\(:[-_0-9a-zA-Z]+:\\)[ \t]*\\(\\S-.*\\(\\S-\\|$\\)\\)")
+ (replace-match (concat "\\1" (format org-property-format
+ (match-string 2) (match-string 3)))
+ t nil))
+ (move-to-column column)))
(defun org-set-autofill-regexps ()
(interactive)
;; text in a line directly attached to a headline would otherwise
;; fill the headline as well.
(org-set-local 'comment-start-skip "^#+[ \t]*")
- (org-set-local 'paragraph-separate "\f\\|\\*\\|[ ]*$\\|[ \t]*[:|]")
+ (org-set-local 'paragraph-separate "\f\\|\\*+ \\|[ ]*$\\|[ \t]*[:|]")
;; The paragraph starter includes hand-formatted lists.
(org-set-local 'paragraph-start
- "\f\\|[ ]*$\\|\\([*\f]+\\)\\|[ \t]*\\([-+*][ \t]+\\|[0-9]+[.)][ \t]+\\)\\|[ \t]*[:|]")
+ "\f\\|[ ]*$\\|\\*+ \\|\f\\|[ \t]*\\([-+*][ \t]+\\|[0-9]+[.)][ \t]+\\)\\|[ \t]*[:|]")
;; Inhibit auto-fill for headers, tables and fixed-width lines.
;; But only if the user has not turned off tables or fixed-width regions
(org-set-local
'auto-fill-inhibit-regexp
- (concat "\\*\\|#\\+"
+ (concat "\\*+ \\|#\\+"
"\\|[ \t]*" org-keyword-time-regexp
(if (or org-enable-table-editor org-enable-fixed-width-editor)
(concat
;; `adaptive-fill-regexp' never matches. Then install our own matcher.
(org-set-local 'adaptive-fill-regexp "\000")
(org-set-local 'adaptive-fill-function
- 'org-adaptive-fill-function))
+ 'org-adaptive-fill-function)
+ (org-set-local
+ 'align-mode-rules-list
+ '((org-in-buffer-settings
+ (regexp . "^#\\+[A-Z_]+:\\(\\s-*\\)\\S-+")
+ (modes . '(org-mode))))))
(defun org-fill-paragraph (&optional justify)
"Re-align a table, pass through to fill-paragraph if no table."
(let ((table-p (org-at-table-p))
(table.el-p (org-at-table.el-p)))
- (cond ((equal (char-after (point-at-bol)) ?*) t) ; skip headlines
- (table.el-p t) ; skip table.el tables
- (table-p (org-table-align) t) ; align org-mode tables
- (t nil)))) ; call paragraph-fill
+ (cond ((and (equal (char-after (point-at-bol)) ?*)
+ (save-excursion (goto-char (point-at-bol))
+ (looking-at outline-regexp)))
+ t) ; skip headlines
+ (table.el-p t) ; skip table.el tables
+ (table-p (org-table-align) t) ; align org-mode tables
+ (t nil)))) ; call paragraph-fill
;; For reference, this is the default value of adaptive-fill-regexp
;; "[ \t]*\\([-|#;>*]+[ \t]*\\|(?[0-9]+[.)][ \t]*\\)*"
work correctly."
(cond ((looking-at "#[ \t]+")
(match-string 0))
- ((looking-at " *\\([-*+] \\|[0-9]+[.)] \\)?")
- (make-string (- (match-end 0) (match-beginning 0)) ?\ ))
+ ((looking-at "[ \t]*\\([-*+] \\|[0-9]+[.)] \\)?")
+ (save-excursion
+ (goto-char (match-end 0))
+ (make-string (current-column) ?\ )))
(t nil)))
-
-(defun org-image-file-name-regexp ()
- "Return regexp matching the file names of images."
- (if (fboundp 'image-file-name-regexp)
- (image-file-name-regexp)
- (let ((image-file-name-extensions
- '("png" "jpeg" "jpg" "gif" "tiff" "tif"
- "xbm" "xpm" "pbm" "pgm" "ppm")))
- (concat "\\."
- (regexp-opt (nconc (mapcar 'upcase
- image-file-name-extensions)
- image-file-name-extensions)
- t)
- "\\'"))))
-
-(defun org-file-image-p (file)
- "Return non-nil if FILE is an image."
- (save-match-data
- (string-match (org-image-file-name-regexp) file)))
-
;;;; Functions extending outline functionality
-;; C-a should go to the beginning of a *visible* line, also in the
-;; new outline.el. I guess this should be patched into Emacs?
-(defun org-beginning-of-line ()
+
+(defun org-beginning-of-line (&optional arg)
"Go to the beginning of the current line. If that is invisible, continue
-to a visible line beginning. This makes the function of C-a more intuitive."
- (interactive)
- (beginning-of-line 1)
- (if (bobp)
- nil
- (backward-char 1)
- (if (org-invisible-p)
- (while (and (not (bobp)) (org-invisible-p))
- (backward-char 1)
- (beginning-of-line 1))
- (forward-char 1))))
+to a visible line beginning. This makes the function of C-a more intuitive.
+If this is a headline, and `org-special-ctrl-a/e' is set, ignore tags on the
+first attempt, and only move to after the tags when the cursor is already
+beyond the end of the headline."
+ (interactive "P")
+ (let ((pos (point)))
+ (beginning-of-line 1)
+ (if (bobp)
+ nil
+ (backward-char 1)
+ (if (org-invisible-p)
+ (while (and (not (bobp)) (org-invisible-p))
+ (backward-char 1)
+ (beginning-of-line 1))
+ (forward-char 1)))
+ (when org-special-ctrl-a/e
+ (cond
+ ((and (looking-at org-todo-line-regexp)
+ (= (char-after (match-end 1)) ?\ ))
+ (goto-char
+ (if (eq org-special-ctrl-a/e t)
+ (cond ((> pos (match-beginning 3)) (match-beginning 3))
+ ((= pos (point)) (match-beginning 3))
+ (t (point)))
+ (cond ((> pos (point)) (point))
+ ((not (eq last-command this-command)) (point))
+ (t (match-beginning 3))))))
+ ((org-at-item-p)
+ (goto-char
+ (if (eq org-special-ctrl-a/e t)
+ (cond ((> pos (match-end 4)) (match-end 4))
+ ((= pos (point)) (match-end 4))
+ (t (point)))
+ (cond ((> pos (point)) (point))
+ ((not (eq last-command this-command)) (point))
+ (t (match-end 4))))))))))
+
+(defun org-end-of-line (&optional arg)
+ "Go to the end of the line.
+If this is a headline, and `org-special-ctrl-a/e' is set, ignore tags on the
+first attempt, and only move to after the tags when the cursor is already
+beyond the end of the headline."
+ (interactive "P")
+ (if (or (not org-special-ctrl-a/e)
+ (not (org-on-heading-p)))
+ (end-of-line arg)
+ (let ((pos (point)))
+ (beginning-of-line 1)
+ (if (looking-at (org-re ".*?\\([ \t]*\\)\\(:[[:alnum:]_@:]+:\\)[ \t]*$"))
+ (if (eq org-special-ctrl-a/e t)
+ (if (or (< pos (match-beginning 1))
+ (= pos (match-end 0)))
+ (goto-char (match-beginning 1))
+ (goto-char (match-end 0)))
+ (if (or (< pos (match-end 0)) (not (eq this-command last-command)))
+ (goto-char (match-end 0))
+ (goto-char (match-beginning 1))))
+ (end-of-line arg)))))
(define-key org-mode-map "\C-a" 'org-beginning-of-line)
+(define-key org-mode-map "\C-e" 'org-end-of-line)
+
+(defun org-kill-line (&optional arg)
+ "Kill line, to tags or end of line."
+ (interactive "P")
+ (cond
+ ((or (not org-special-ctrl-k)
+ (bolp)
+ (not (org-on-heading-p)))
+ (call-interactively 'kill-line))
+ ((looking-at (org-re ".*?\\S-\\([ \t]+\\(:[[:alnum:]_@:]+:\\)\\)[ \t]*$"))
+ (kill-region (point) (match-beginning 1))
+ (org-set-tags nil t))
+ (t (kill-region (point) (point-at-eol)))))
+
+(define-key org-mode-map "\C-k" 'org-kill-line)
(defun org-invisible-p ()
"Check if point is at a character currently not visible."
(defalias 'org-back-to-heading 'outline-back-to-heading)
(defalias 'org-on-heading-p 'outline-on-heading-p)
+(defalias 'org-at-heading-p 'outline-on-heading-p)
+(defun org-at-heading-or-item-p ()
+ (or (org-on-heading-p) (org-at-item-p)))
(defun org-on-target-p ()
(or (org-in-regexp org-radio-target-regexp)
(outline-up-heading-all arg) ; emacs 21 version of outline.el
(outline-up-heading arg t))) ; emacs 22 version of outline.el
+(defun org-up-heading-safe ()
+ "Move to the heading line of which the present line is a subheading.
+This version will not throw an error. It will return the level of the
+headline found, or nil if no higher level is found."
+ (let ((pos (point)) start-level level
+ (re (concat "^" outline-regexp)))
+ (catch 'exit
+ (outline-back-to-heading t)
+ (setq start-level (funcall outline-level))
+ (if (equal start-level 1) (throw 'exit nil))
+ (while (re-search-backward re nil t)
+ (setq level (funcall outline-level))
+ (if (< level start-level) (throw 'exit level)))
+ nil)))
+
+(defun org-first-sibling-p ()
+ "Is this heading the first child of its parents?"
+ (interactive)
+ (let ((re (concat "^" outline-regexp))
+ level l)
+ (unless (org-at-heading-p t)
+ (error "Not at a heading"))
+ (setq level (funcall outline-level))
+ (save-excursion
+ (if (not (re-search-backward re nil t))
+ t
+ (setq l (funcall outline-level))
+ (< l level)))))
+
(defun org-goto-sibling (&optional previous)
"Goto the next sibling, even if it is invisible.
When PREVIOUS is set, go to the previous sibling instead. Returns t
(pos (point))
(re (concat "^" outline-regexp))
level l)
- (org-back-to-heading t)
- (setq level (funcall outline-level))
- (catch 'exit
- (or previous (forward-char 1))
- (while (funcall fun re nil t)
- (setq l (funcall outline-level))
- (when (< l level) (goto-char pos) (throw 'exit nil))
- (when (= l level) (goto-char (match-beginning 0)) (throw 'exit t)))
- (goto-char pos)
- nil)))
+ (when (condition-case nil (org-back-to-heading t) (error nil))
+ (setq level (funcall outline-level))
+ (catch 'exit
+ (or previous (forward-char 1))
+ (while (funcall fun re nil t)
+ (setq l (funcall outline-level))
+ (when (< l level) (goto-char pos) (throw 'exit nil))
+ (when (= l level) (goto-char (match-beginning 0)) (throw 'exit t)))
+ (goto-char pos)
+ nil))))
(defun org-show-siblings ()
"Show all siblings of the current headline."
(save-excursion
(and (outline-next-heading)
(org-flag-heading nil))))
- (outline-flag-region (max 1 (1- (point)))
+ (outline-flag-region (max (point-min) (1- (point)))
(save-excursion (outline-end-of-heading) (point))
flag))))
-(defun org-end-of-subtree (&optional invisible-OK)
+(defun org-end-of-subtree (&optional invisible-OK to-heading)
;; This is an exact copy of the original function, but it uses
;; `org-back-to-heading', to make it work also in invisible
;; trees. And is uses an invisible-OK argument.
(or first (> (funcall outline-level) level)))
(setq first nil)
(outline-next-heading))
- (if (memq (preceding-char) '(?\n ?\^M))
- (progn
- ;; Go to end of line before heading
- (forward-char -1)
- (if (memq (preceding-char) '(?\n ?\^M))
- ;; leave blank line before heading
- (forward-char -1)))))
+ (unless to-heading
+ (if (memq (preceding-char) '(?\n ?\^M))
+ (progn
+ ;; Go to end of line before heading
+ (forward-char -1)
+ (if (memq (preceding-char) '(?\n ?\^M))
+ ;; leave blank line before heading
+ (forward-char -1))))))
(point))
(defun org-show-subtree ()
Show the heading too, if it is currently invisible."
(interactive)
(save-excursion
- (org-back-to-heading t)
- (outline-flag-region
- (max 1 (1- (point)))
- (save-excursion
- (re-search-forward (concat "[\r\n]\\(" outline-regexp "\\)") nil 'move)
- (or (match-beginning 1) (point-max)))
- nil)))
+ (condition-case nil
+ (progn
+ (org-back-to-heading t)
+ (outline-flag-region
+ (max (point-min) (1- (point)))
+ (save-excursion
+ (re-search-forward
+ (concat "[\r\n]\\(" outline-regexp "\\)") nil 'move)
+ (or (match-beginning 1) (point-max)))
+ nil))
+ (error nil))))
(defun org-make-options-regexp (kwds)
"Make a regular expression for keyword lines."
(remove-hook 'post-command-hook 'org-isearch-post-command 'local)
(org-show-context 'isearch))
-;;;; Repair problems with some other packages
+
+;;;; Integration with and fixes for other packages
+
+;;; Imenu support
+
+(defvar org-imenu-markers nil
+ "All markers currently used by Imenu.")
+(make-variable-buffer-local 'org-imenu-markers)
+
+(defun org-imenu-new-marker (&optional pos)
+ "Return a new marker for use by Imenu, and remember the marker."
+ (let ((m (make-marker)))
+ (move-marker m (or pos (point)))
+ (push m org-imenu-markers)
+ m))
+
+(defun org-imenu-get-tree ()
+ "Produce the index for Imenu."
+ (mapc (lambda (x) (move-marker x nil)) org-imenu-markers)
+ (setq org-imenu-markers nil)
+ (let* ((n org-imenu-depth)
+ (re (concat "^" outline-regexp))
+ (subs (make-vector (1+ n) nil))
+ (last-level 0)
+ m tree level head)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-max))
+ (while (re-search-backward re nil t)
+ (setq level (org-reduced-level (funcall outline-level)))
+ (when (<= level n)
+ (looking-at org-complex-heading-regexp)
+ (setq head (org-match-string-no-properties 4)
+ m (org-imenu-new-marker))
+ (org-add-props head nil 'org-imenu-marker m 'org-imenu t)
+ (if (>= level last-level)
+ (push (cons head m) (aref subs level))
+ (push (cons head (aref subs (1+ level))) (aref subs level))
+ (loop for i from (1+ level) to n do (aset subs i nil)))
+ (setq last-level level)))))
+ (aref subs 1)))
+
+(eval-after-load "imenu"
+ '(progn
+ (add-hook 'imenu-after-jump-hook
+ (lambda () (org-show-context 'org-goto)))))
+
+;; Speedbar support
+
+(defun org-speedbar-set-agenda-restriction ()
+ "Restrict future agenda commands to the location at point in speedbar.
+To get rid of the restriction, use \\[org-agenda-remove-restriction-lock]."
+ (interactive)
+ (let (p m tp np dir txt w)
+ (cond
+ ((setq p (text-property-any (point-at-bol) (point-at-eol)
+ 'org-imenu t))
+ (setq m (get-text-property p 'org-imenu-marker))
+ (save-excursion
+ (save-restriction
+ (set-buffer (marker-buffer m))
+ (goto-char m)
+ (org-agenda-set-restriction-lock 'subtree))))
+ ((setq p (text-property-any (point-at-bol) (point-at-eol)
+ 'speedbar-function 'speedbar-find-file))
+ (setq tp (previous-single-property-change
+ (1+ p) 'speedbar-function)
+ np (next-single-property-change
+ tp 'speedbar-function)
+ dir (speedbar-line-directory)
+ txt (buffer-substring-no-properties (or tp (point-min))
+ (or np (point-max))))
+ (save-excursion
+ (save-restriction
+ (set-buffer (find-file-noselect
+ (let ((default-directory dir))
+ (expand-file-name txt))))
+ (unless (org-mode-p)
+ (error "Cannot restrict to non-Org-mode file"))
+ (org-agenda-set-restriction-lock 'file))))
+ (t (error "Don't know how to restrict Org-mode's agenda")))
+ (org-move-overlay org-speedbar-restriction-lock-overlay
+ (point-at-bol) (point-at-eol))
+ (setq current-prefix-arg nil)
+ (org-agenda-maybe-redo)))
+
+(eval-after-load "speedbar"
+ '(progn
+ (speedbar-add-supported-extension ".org")
+ (define-key speedbar-file-key-map "<" 'org-speedbar-set-agenda-restriction)
+ (define-key speedbar-file-key-map "\C-c\C-x<" 'org-speedbar-set-agenda-restriction)
+ (define-key speedbar-file-key-map ">" 'org-agenda-remove-restriction-lock)
+ (define-key speedbar-file-key-map "\C-c\C-x>" 'org-agenda-remove-restriction-lock)
+ (add-hook 'speedbar-visiting-tag-hook
+ (lambda () (org-show-context 'org-goto)))))
+
+
+;;; Fixes and Hacks
+
+;; Make flyspell not check words in links, to not mess up our keymap
+(defun org-mode-flyspell-verify ()
+ "Don't let flyspell put overlays at active buttons."
+ (not (get-text-property (point) 'keymap)))
;; Make `bookmark-jump' show the jump location if it was hidden.
(eval-after-load "bookmark"
;;;; Experimental code
+(defun org-closed-in-range ()
+ "Sparse tree of items closed in a certain time range.
+Still experimental, may disappear in the future."
+ (interactive)
+ ;; Get the time interval from the user.
+ (let* ((time1 (time-to-seconds
+ (org-read-date nil 'to-time nil "Starting date: ")))
+ (time2 (time-to-seconds
+ (org-read-date nil 'to-time nil "End date:")))
+ ;; callback function
+ (callback (lambda ()
+ (let ((time
+ (time-to-seconds
+ (apply 'encode-time
+ (org-parse-time-string
+ (match-string 1))))))
+ ;; check if time in interval
+ (and (>= time time1) (<= time time2))))))
+ ;; make tree, check each match with the callback
+ (org-occur "CLOSED: +\\[\\(.*?\\)\\]" nil callback)))
+
;;;; Finish up
a negative argument ARG = -N means move forward N paragraphs.
A paragraph start is the beginning of a line which is a
-`first-line-of-paragraph' or which is ordinary text and follows a
-paragraph-separating line; except: if the first real line of a
+`paragraph-start' or which is ordinary text and follows a
+`paragraph-separate'ing line; except: if the first real line of a
paragraph is preceded by a blank line, the paragraph starts at that
blank line.
(with-syntax-table tex-error-parse-syntax-table
(backward-up-list 1)
(skip-syntax-forward "(_")
- (while (not (file-readable-p (thing-at-point 'filename)))
+ (while (not
+ (and (setq try-filename (thing-at-point
+ 'filename))
+ (not (string= "" try-filename))
+ (file-readable-p try-filename)))
(skip-syntax-backward "(_")
(backward-up-list 1)
(skip-syntax-forward "(_"))
Info node `(elisp)Tool Bar'. Items are added from left to right.
ICON is the base name of a file containing the image to use. The
-function will first try to use low-color/ICON.xpm if display-color-cells
+function will first try to use low-color/ICON.xpm if `display-color-cells'
is less or equal to 256, then ICON.xpm, then ICON.pbm, and finally
ICON.xbm, using `find-image'.
(setq dirname (directory-file-name dirname)))
(setq n (1- n))
(push (if (zerop (length file)) ;nil or "".
- (prog1 "" (setq dirname nil)) ;Could be `dirname' iso "".
+ (prog1 (or (file-remote-p dirname) "")
+ (setq dirname nil)) ;Could be `dirname' iso "".
file)
extra-string)))
(when (zerop n)
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
+2008-08-30 Glenn Morris <rgm@gnu.org>
+
+ * url-http.el (url-https-expand-file-name): Resolve directly to
+ url-default-expander rather than via another alias.
+ (url-default-expander): Autoload an autoload. (Bug#825).
+
+2008-04-04 Magnus Henoch <mange@freemail.hu>
+
+ * url-http.el (url-http-chunked-encoding-after-change-function):
+ Remove superfluous CRLF at end of file. (bug #42)
+
+2008-03-31 John Wiegley <johnw@newartisans.com>
+
+ * url-auth.el (url-digest-auth): Changed an if so that the
+ interaction between the PROMPT and OVERWRITE arguments can no
+ longer result in the user being queried twice for the same login
+ and password information.
+
2008-02-28 Teodor Zlatanov <tzz@lifelogs.com>
* url-util.el (url-get-normalized-date): Simplify
(string= data (substring file 0 (length data)))))
(setq retval (cdr (car byserv))))
(setq byserv (cdr byserv))))
- (if (or (and (not retval) prompt) overwrite)
- (progn
- (setq user (read-string (url-auth-user-prompt url realm)
- (user-real-login-name))
- pass (read-passwd "Password: ")
- retval (setq retval
- (cons user
- (url-digest-auth-create-key
- user pass realm
- (or url-request-method "GET")
- url)))
- byserv (assoc server url-digest-auth-storage))
+ (if overwrite
+ (if (and (not retval) prompt)
+ (setq user (read-string (url-auth-user-prompt url realm)
+ (user-real-login-name))
+ pass (read-passwd "Password: ")
+ retval (setq retval
+ (cons user
+ (url-digest-auth-create-key
+ user pass realm
+ (or url-request-method "GET")
+ url)))
+ byserv (assoc server url-digest-auth-storage))
(setcdr byserv
(cons (cons file retval) (cdr byserv))))))
(t (setq retval nil)))
(url-http-debug "Saw end of stream chunk!")
(setq read-next-chunk nil)
(url-display-percentage nil nil)
- (goto-char (match-end 1))
+ ;; Every chunk, even the last 0-length one, is
+ ;; terminated by CRLF. Skip it.
+ (when (looking-at "\r?\n")
+ (url-http-debug "Removing terminator of last chunk")
+ (delete-region (match-beginning 0) (match-end 0)))
(if (re-search-forward "^\r*$" nil t)
(url-http-debug "Saw end of trailers..."))
(if (url-http-parse-headers)
(defconst url-https-default-port 443 "Default HTTPS port.")
;;;###autoload
(defconst url-https-asynchronous-p t "HTTPS retrievals are asynchronous.")
+;;;###autoload (autoload 'url-default-expander "url-expand")
;;;###autoload
-(defalias 'url-https-expand-file-name 'url-http-expand-file-name)
+(defalias 'url-https-expand-file-name 'url-default-expander)
(defmacro url-https-create-secure-wrapper (method args)
`(defun ,(intern (format (if method "url-https-%s" "url-https") method)) ,args
(vc-hg-command buffer 0 file "annotate" "-d" "-n" (if version (concat "-r" version)))
(with-current-buffer buffer
(goto-char (point-min))
- (re-search-forward "^[0-9]")
- (delete-region (point-min) (1- (point)))))
+ (re-search-forward "^[ \t]*[0-9]")
+ (delete-region (point-min) (match-beginning 0))))
;; The format for one line output by "hg annotate -d -n" looks like this:
;;215 Wed Jun 20 21:22:58 2007 -0700: CONTENTS
;; i.e: VERSION_NUMBER DATE: CONTENTS
-(defconst vc-hg-annotate-re "^[ \t]*\\([0-9]+\\) \\(.\\{30\\}\\): ")
+;; If the user has set the "--follow" option, the output looks like:
+;;215 Wed Jun 20 21:22:58 2007 -0700 foo.c: CONTENTS
+;; i.e. VERSION_NUMBER DATE FILENAME: CONTENTS
+(defconst vc-hg-annotate-re
+ "^[ \t]*\\([0-9]+\\) \\(.\\{30\\}\\)[^:\n]*\\(:[^ \n][^:\n]*\\)*: ")
(defun vc-hg-annotate-time ()
(when (looking-at vc-hg-annotate-re)
(defun vc-hg-annotate-extract-revision-at-line ()
(save-excursion
(beginning-of-line)
- (if (looking-at vc-hg-annotate-re) (match-string-no-properties 1))))
+ (when (looking-at vc-hg-annotate-re) (match-string-no-properties 1))))
(defun vc-hg-previous-version (file rev)
(let ((newrev (1- (string-to-number rev))))
(when (and (not (eq t okstatus))
(or (not (integerp status))
(and okstatus (< okstatus status))))
- (pop-to-buffer (current-buffer))
- (goto-char (point-min))
- (shrink-window-if-larger-than-buffer)
+ ;; Don't show internal temp buffers. Especially since, together
+ ;; with with-temp-buffer and pop-up-frames, this can result in
+ ;; bugs where with-temp-buffer ends up not preserving
+ ;; current-buffer (because kill-buffer doesn't preserve it).
+ (unless (eq ?\s (aref (buffer-name (current-buffer)) 0))
+ (pop-to-buffer (current-buffer))
+ (goto-char (point-min))
+ (shrink-window-if-larger-than-buffer))
(error "Running %s...FAILED (%s)" command
(if (integerp status) (format "status %d" status) status))))
(if vc-command-messages
(defconst emacs-copyright "Copyright (C) 2008 Free Software Foundation, Inc."
"Short copyright string for this version of Emacs.")
-(defconst emacs-version "22.2" "\
+(defconst emacs-version "22.3" "\
Version numbers of this version of Emacs.")
(defconst emacs-major-version
(insert " -- ")
(woman-forward-arg 'unquote 'concat)
;; Delete repeated arguments:
- (if (string-match (buffer-substring here (point))
+ (if (string-equal (buffer-substring here (point))
(buffer-substring start here))
- (delete-region here (point)))
- ))
+ (delete-region here (point)))))
;; Embolden heading (point is at end of heading):
(woman-set-face
(save-excursion (beginning-of-line) (point)) (point) 'woman-bold)
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
2008-03-26 Chong Yidong <cyd@stupidchicken.com>
* Version 22.2 released.
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
+2008-04-06 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * makefile.MPW (MacObjects): Add mactoolbox.c.x.
+ (mactoolbox.c.x): New target.
+
2008-03-26 Chong Yidong <cyd@stupidchicken.com>
* Version 22.2 released.
/* Localized versions of Info.plist keys */
CFBundleName = "Emacs";
-CFBundleShortVersionString = "22.2";
-CFBundleGetInfoString = "22.2, Copyright (C) 2008 Free Software Foundation, Inc.";
+CFBundleShortVersionString = "22.3";
+CFBundleGetInfoString = "22.3, Copyright (C) 2008 Free Software Foundation, Inc.";
"{Src}macfns.c.x" ¶
"{Src}macmenu.c.x" ¶
"{Src}macselect.c.x" ¶
- "{Src}macterm.c.x"
+ "{Src}macterm.c.x" ¶
+ "{Src}mactoolbox.c.x"
StdLibraries = ¶
"{SharedLibraries}CarbonLib" ¶
"{Src}coding.h" ¶
"{Src}ccl.h"
+{Src}mactoolbox.c.x Ä ¶
+ {CONFIG_H_GROUP} ¶
+ "{Src}lisp.h" ¶
+ "{Src}macterm.h" ¶
+ "{Src}macgui.h" ¶
+ "{Src}frame.h" ¶
+ "{Src}charset.h" ¶
+ "{Src}coding.h" ¶
+ "{Src}ccl.h" ¶
+ {DISPEXTERN_H_GROUP} ¶
+ "{Src}fontset.h" ¶
+ "{Src}termhooks.h" ¶
+ "{Src}buffer.h" ¶
+ "{Src}window.h" ¶
+ "{Src}keyboard.h" ¶
+ {BLOCKINPUT_H_GROUP}
+
#----------------------------------------#
# Variables and rules for target "Clean" #
resource 'vers' (1) {
0x22, /* Major revision in BCD */
- 0x2, /* Minor revision in BCD */
+ 0x3, /* Minor revision in BCD */
final, /* development, alpha, beta, or final (release) */
0, /* Non-final release # */
0, /* Region code */
- "22.2", /* Short version number */
- "22.2, Copyright \0xa9 2008 "
+ "22.3", /* Short version number */
+ "22.3, Copyright \0xa9 2008 "
"Free Software Foundation, Inc." /* Long version number */
};
echo "Making links to \`nt'"
(cd nt
- ln emacs.manifest emacs.rc config.nt [a-z]*.c ../${tempdir}/nt
+ ln emacs.manifest emacs.rc emacsclient.rc config.nt [a-z]*.c ../${tempdir}/nt
ln nmake.defs gmake.defs subdirs.el ../${tempdir}/nt
ln [a-z]*.bat [a-z]*.h ../${tempdir}/nt
ln ChangeLog INSTALL README makefile.w32-in ../${tempdir}/nt)
cd ../${tempdir}/info
# Avoid an error when expanding the wildcards later.
ln emacs dummy~ ; ln emacs \#dummy\#
- rm -f *~ \#*\# core)
+ rm -f *~ \#*\# core .arch-inventory)
echo "Making links to \`man'"
(cd man
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
+2008-08-23 Glenn Morris <rgm@gnu.org>
+
+ * dired-x.texi (Shell Command Guessing):
+ Mention dired-guess-shell-case-fold-search. (Bug#417)
+
+2008-06-15 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus-faq.texi: Generate. Change node names to "FAQ N-M".
+
+ * gnus-faq.texi: Generate from gnus-faq.xml (sourceforge.net).
+
+2008-06-15 Frank Schmitt <ich@frank-schmitt.net>
+
+ * gnus-faq.texi ([5.12]): Add entry about message-kill-buffer-on-exit.
+ Fix a typo.
+
+2008-06-15 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus.texi (Mail Source Customization): Correct values of
+ `mail-source-delete-incoming'. Reported by Tassilo Horn.
+ (Oort Gnus): Fix version comment for mml-dnd-protocol-alist.
+
+2008-05-10 Eli Zaretskii <eliz@gnu.org>
+
+ * msdog.texi (Windows Files): Update the documentation of
+ w32-get-true-file-attributes.
+
+2008-05-08 Chong Yidong <cyd@stupidchicken.com>
+
+ * killing.texi (Appending Kills): Remove a strangely off-topic index
+ entry "television".
+
+2008-04-13 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus-faq.texi ([5.2]): Adjust for message-fill-column.
+
+ * gnus.texi (Oort Gnus): Add message-fill-column.
+
+ * message.texi (Various Message Variables): Add message-fill-column.
+
+2008-04-12 Adrian Aichner <adrian@xemacs.org>
+
+ * gnus.texi (Mail Source Specifiers): Typo fix.
+
+2008-04-12 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus.texi (Diary Headers Generation): Update key binding for
+ `gnus-diary-check-message'.
+
+2008-04-11 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus.texi, gnus-faq.texi, message.texi: Bump version to 5.10.11.
+
+2008-04-11 Mirko Vukovic <mirko.vukovic@gmail.com> (tiny change)
+
+ * maintaining.texi (Maintaining):
+ * emacs.texi (Top): Typo.
+
+2008-04-10 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus.texi, gnus-faq.texi, message.texi: Gnus v5.10.10 is released.
+
+2008-04-10 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus.texi (Emacsen): Give recommendations for Emacs 22 and Emacs 23.
+
+2008-04-09 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus.texi (Oort Gnus): Mention customizing of tool bars.
+
+2008-04-09 Michael Albinus <michael.albinus@gmx.de>
+
+ * trampver.texi: Update release number.
+
+2008-04-08 Carsten Dominik <dominik@science.uva.nl>
+
+ * org.texi: Large scale rewrite and changes, moving from version 4.67
+ to version 5.23.
+
+2008-03-28 Jason Rumney <jasonr@gnu.org>
+
+ * display.texi (Display Custom): Mention overlay-margin in text.
+
2008-03-26 Chong Yidong <cyd@stupidchicken.com>
* Version 22.2 released.
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
2008-03-26 Chong Yidong <cyd@stupidchicken.com>
* Version 22.2 released.
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
+2008-04-11 Eli Zaretskii <eliz@gnu.org>
+
+ * makefile.w32-in (ALL): Move $(CLIENTRES) from here...
+ (all): ...to here. $(ALL) is a prerequisite of .PHONY, so having
+ a real file there is not a good idea.
+
+2008-04-10 Jason Rumney <jasonr@gnu.org>
+
+ * emacsclient.rc: New file.
+
+ * makefile.w32-in (CLIENTRES): New variable and build target.
+ (all): Depend on it.
+ ($(TRES)): Use $(TRES) in rule.
+
2008-03-26 Chong Yidong <cyd@stupidchicken.com>
* Version 22.2 released.
#endif
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 22,2,0,0
- PRODUCTVERSION 22,2,0,0
+ FILEVERSION 22,3,0,0
+ PRODUCTVERSION 22,3,0,0
FILEFLAGSMASK 0x3FL
#ifdef EMACSDEBUG
FILEFLAGS 0x1L
BEGIN
VALUE "CompanyName", "Free Software Foundation\0"
VALUE "FileDescription", "GNU Emacs for Windows NT/95/98/2000/ME/XP\0"
- VALUE "FileVersion", "22, 2, 0, 0\0"
+ VALUE "FileVersion", "22, 3, 0, 0\0"
VALUE "InternalName", "Emacs\0"
VALUE "LegalCopyright", "Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008\0"
VALUE "OriginalFilename", "emacs.exe"
VALUE "ProductName", "Emacs: The extensible self-documenting text editor\0"
- VALUE "ProductVersion", "22, 2, 0, 0\0"
+ VALUE "ProductVersion", "22, 3, 0, 0\0"
VALUE "OLESelfRegister", "\0"
END
END
--- /dev/null
+Emacs ICON icons\emacs.ico
+
+#ifndef VS_VERSION_INFO
+#define VS_VERSION_INFO 1
+#endif
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 22,3,0,0
+ PRODUCTVERSION 22,3,0,0
+ FILEFLAGSMASK 0x3FL
+#ifdef EMACSDEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0"
+ BEGIN
+ VALUE "CompanyName", "Free Software Foundation\0"
+ VALUE "FileDescription", "GNU EmacsClient for Windows NT/95/98/2000/ME/XP\0"
+ VALUE "FileVersion", "22, 3, 0, 0\0"
+ VALUE "InternalName", "EmacsClient\0"
+ VALUE "LegalCopyright", "Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008\0"
+ VALUE "OriginalFilename", "emacsclientw.exe"
+ VALUE "ProductName", "EmacsClient: Client for the extensible self-documenting text editor\0"
+ VALUE "ProductVersion", "22, 3, 0, 0\0"
+ VALUE "OLESelfRegister", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
# FIXME: This file uses DOS EOLs. Convert to Unix after 22.1 is out\r
# (and remove or replace this comment).\r
\r
+TRES = $(BLD)/emacs.res\r
+CLIENTRES = $(BLD)/emacsclient.res\r
+\r
+XMFLAGS =\r
+\r
ALL = addpm ddeclient runemacs cmdproxy addsection preprep\r
\r
.PHONY: $(ALL)\r
\r
-TRES = $(BLD)/emacs.res\r
-\r
-XMFLAGS =\r
\r
addpm: stamp_BLD $(BLD)/addpm.exe\r
$(BLD)/addpm.exe: $(BLD)/addpm.$(O)\r
# it is not necessary on later versions, it is still ok to use it.\r
#\r
$(TRES): emacs.rc stamp_BLD\r
- $(RC) $(RC_OUT)$(BLD)/emacs.res emacs.rc\r
+ $(RC) $(RC_OUT)$(TRES) emacs.rc\r
+\r
+$(CLIENTRES): emacsclient.rc stamp_BLD\r
+ $(RC) $(RC_OUT)$(CLIENTRES) emacsclient.rc\r
\r
runemacs: stamp_BLD $(BLD)/runemacs.exe\r
$(BLD)/runemacs.exe: $(BLD)/runemacs.$(O) $(TRES)\r
#\r
# Build emacs\r
#\r
-all: which-sh stamp_BLD $(ALL) maybe-bootstrap all-other-dirs-$(MAKETYPE)\r
+all: which-sh stamp_BLD $(ALL) $(CLIENTRES) maybe-bootstrap all-other-dirs-$(MAKETYPE)\r
\r
all-other-dirs-nmake: addsection\r
cd ..\lib-src\r
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
2008-03-26 Chong Yidong <cyd@stupidchicken.com>
* Version 22.2 released.
+2008-09-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * Version 22.3 released.
+
+2008-09-02 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macterm.c (mac_draw_rectangle) [USE_CG_DRAWING]:
+ Fix rectangle calculation.
+
+2008-08-30 Glenn Morris <rgm@gnu.org>
+
+ * frame.c (Fmodify_frame_parameters): Doc fix.
+
+2008-08-30 Eli Zaretskii <eliz@gnu.org>
+
+ * w32.c (stat): Only root directory passed to GetDriveType. Allow
+ RAM disk as well as local fixed disk when
+ w32-get-true-file-attributes is set to `local'.
+
+2008-08-30 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macterm.c [USE_CG_DRAWING] (mac_draw_cg_image):
+ Fix coordinate flipping.
+ [USE_ATSUI] (mac_draw_image_string_atsui) [MAC_OS_X]: Likewise.
+ [USE_CG_TEXT_DRAWING] (mac_draw_image_string_cg): Likewise.
+
+2008-08-29 Eli Zaretskii <eliz@gnu.org>
+
+ * fileio.c (Fexpand_file_name): Copy argument `name' into local
+ storage on all platforms, not just on DOS_NT.
+
+2008-08-29 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * mac.c (mac_system_script_code): Use EMACS_INT for DEFVAR_INT variable.
+ [MAC_OSX] (mac_try_close_socket, sys_select) [SELECT_USE_CFSOCKET]:
+ Cast to pointer-size integer before casting to pointer.
+
+ * macmenu.c [HAVE_DIALOGS] (mac_dialog_show): Cast to pointer-size
+ integer before casting to pointer.
+
+ * macselect.c (Fmac_resume_apple_event): Distribute cast to pointer
+ over conditional branches.
+
+2008-08-26 Chong Yidong <cyd@stupidchicken.com>
+
+ * eval.c (Fcondition_case): Doc fix.
+
+2008-08-26 Jason Rumney <jasonr@gnu.org>
+
+ * w32menu.c (Fx_popup_menu, Fx_popup_dialog, w32_menu_show): Ensure
+ mouse is not grabbed after menu is finished.
+
+2008-08-26 Juanma Barranquero <lekktu@gmail.com>
+
+ * editfns.c (Ffield_string_no_properties): Fix typo in docstring.
+
+ * fringe.c (Fdefine_fringe_bitmap): Doc fix.
+
+ * minibuf.c (Fread_minibuffer, Feval_minibuffer): Reflow docstring.
+
+ * textprop.c (syms_of_textprop) <text-property-default-nonsticky>:
+ (Fremove_text_properties): Fix typos in docstrings.
+
+ * w32fns.c (Fw32_define_rgb_color): Fix typo in docstring.
+
+ * xdisp.c (syms_of_xdisp) <scroll-conservatively>:
+ Fix typo in docstring.
+
+ * xfaces.c (Fx_list_fonts, Finternal_copy_lisp_face):
+ Fix typos in docstrings.
+
+ * xselect.c (Fx_send_client_event): Doc fix.
+
+2008-08-23 Jason Rumney <jasonr@gnu.org>
+
+ * image.c (gif_format): Use :index, not :image.
+
+2008-08-21 \e$,1 P\e(Bsmail D\e,Av\e(Bnmez <ismail@namtrac.org> (tiny change)
+
+ * xterm.c (x_delete_display): Don't call XrmDestroyDatabase on GTK+.
+
+2008-08-20 Andreas Schwab <schwab@suse.de>
+
+ * print.c (print_object): Fix off-by-one in last change.
+
+2008-08-20 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macterm.c (x_load_font): Round average width to the nearest integer.
+
+ * mactoolbox.c [USE_MAC_TSM] (mac_handle_text_input_event):
+ Check if display is up to date before accessing current matrix.
+
+2008-08-15 Chong Yidong <cyd@stupidchicken.com>
+
+ * process.c (make_process): Initialize kill_without_query struct
+ member.
+
+2008-08-10 Glenn Morris <rgm@gnu.org>
+
+ Sync from trunk 2008-07-08:
+ * m/sparc.h: Define __sparc__ rather than sparc. (Bug#507.)
+ * alloc.c, ecrt0.c: Use __sparc__ rather than sparc.
+
+ * unexsunos4.c: Use __sparc__ rather than sparc.
+
+2008-08-08 Chong Yidong <cyd@stupidchicken.com>
+
+ * xdisp.c (move_it_to): When stopping at a charpos, check if
+ that's a continued multi-char glyph; if so, advance to the actual
+ glyph.
+ (try_window): Check scroll margin on bottom window edge too.
+
+2008-08-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * xdisp.c (redisplay_window): Don't enforce scroll-margin when
+ forcing a window start.
+
+ * fileio.c (Vauto_save_list_file_name): Move here from file.el.
+ (auto_save_1): Update modtime when auto-save-list-file-name is on.
+
+2008-08-03 Andreas Schwab <schwab@suse.de>
+
+ * vm-limit.c (get_lim_data) [HAVE_GETRLIMIT && RLIMIT_AS]: Define.
+ (check_memory_limits): Don't handle HAVE_GETRLIMIT here.
+
+2008-08-02 Chong Yidong <cyd@stupidchicken.com>
+
+ * vm-limit.c (check_memory_limits): Don't use getrlimit on cygwin.
+ Don't use uninitialized pointer variable when using getrlimit.
+
+2008-08-02 Eli Zaretskii <eliz@gnu.org>
+
+ * fileio.c (Fexpand_file_name): Convert the value of $HOME to a
+ multibyte string.
+
+2008-08-01 Jason Rumney <jasonr@gnu.org>
+
+ * w32term.c (x_draw_composite_glyph_string_foreground): Force
+ use of Unicode output.
+
+2008-07-30 Jan Dj\e,Ad\e(Brv <jan.h.d@swipnet.se>
+
+ * xmenu.c (Fx_menu_bar_open_internal): Use activate_item signal to
+ open menu.
+
+ * gtkutil.c (menu_nav_ended): Remove.
+ (create_menus): Remove signal connect for menu_nav_ended.
+ (create_menus): Connect selection-done to menu_nav_ended.
+
+2008-07-26 Eli Zaretskii <eliz@gnu.org>
+
+ * term.c (syms_of_term): Fix last change.
+
+2008-07-25 Chong Yidong <cyd@stupidchicken.com>
+
+ * term.c (syms_of_term): Initialize default_orig_pair,
+ default_set_foreground, and default_set_background.
+
+ * getloadavg.c (nl): Rename to name_list to avoid ncurses.h
+ clash (bug#86).
+ (getloadavg): Callers changed.
+
+2008-07-22 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macterm.c (XDrawLine) [USE_MAC_IMAGE_IO]: Remove spurious return.
+
+2008-07-21 Ami Fischman <ami@fischman.org> (tiny change)
+
+ * print.c (print_object): Check print_depth before searching for
+ circularities.
+
+2008-07-21 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macterm.h (kCGBitmapByteOrder32Host): New define for
+ non-universal SDKs.
+
+ * image.c (mac_create_cg_image_from_image, image_load_image_io)
+ [USE_MAC_IMAGE_IO]: Remove conditionals for kCGBitmapByteOrder32Host.
+
+ * macterm.c (XDrawLine, XCreatePixmapFromBitmapData) [USE_MAC_IMAGE_IO]:
+ Remove conditionals for kCGBitmapByteOrder32Host.
+
+2008-07-18 David Robinow <drobinow@gmail.com> (tiny change)
+
+ * w32inevt.c: Include dispextern.h. Don't declare change_frame_size
+ here.
+ (maybe_generate_resize_event, resize_event): Call change_frame_size
+ with SAFE arg.
+
+2008-07-17 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * gtkutil.c: Include <config.h> instead of "config.h".
+
+ * lisp.h (Foverlay_buffer): Add EXFUN.
+
+ * process.c (create_process) [!WINDOWSNT && FD_CLOEXEC]: Wait for
+ child process to complete child_setup. Undo 2005-09-21 change.
+
+ * s/darwin.h: Mention setsid after vfork.
+
+2008-07-11 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * Makefile.in (frame.o, keyboard.o, xdisp.o, xfaces.o):
+ Depend on macgui.h.
+
+ * macfns.c (Fx_server_version): Don't use gestaltSystemVersionMajor,
+ gestaltSystemVersionMinor, or gestaltSystemVersionBugFix.
+
+ * macterm.c (keycode_to_xkeysym_table): Add entries for f17, f18,
+ and f19.
+ [MAC_OSX] (fn_keycode_to_keycode_table): Likewise.
+
+ * macterm.h (gestaltSystemVersionMajor, gestaltSystemVersionMinor)
+ (gestaltSystemVersionBugFix) [MAC_OS_X_VERSION_MAX_ALLOWED < 1040]:
+ Remove enumerators.
+
+ * mactoolbox.c [USE_MAC_TSM] (mac_handle_text_input_event):
+ Check if FACE_FROM_ID returns NULL.
+
+2008-07-07 Chong Yidong <cyd@stupidchicken.com>
+
+ * image.c (png_load): Use correct bit-depth for setting background
+ color.
+
+2008-05-15 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macterm.c (x_draw_relief_rect): Remove unused variable `dpy'.
+ [TARGET_API_MAC_CARBON] (mac_store_event_ref_as_apple_event):
+ Fix last change.
+
+2008-05-13 Jan Dj\e,Ad\e(Brv <jan.h.d@swipnet.se>
+
+ * xterm.c (handle_one_xevent): Don't pass buttons higher than 3
+ to Gtk+ menus.
+
+2008-05-12 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * emacs.c (main_thread): Conditionalize on
+ FORWARD_SIGNAL_TO_MAIN_THREAD instead of HAVE_GTK_AND_PTHREAD.
+ (main) [FORWARD_SIGNAL_TO_MAIN_THREAD]: Initialize it.
+
+ * syssignal.h (FORWARD_SIGNAL_TO_MAIN_THREAD): New define.
+ (main_thread, SIGNAL_THREAD_CHECK): Conditionalize on
+ FORWARD_SIGNAL_TO_MAIN_THREAD instead of HAVE_GTK_AND_PTHREAD.
+
+2008-05-10 Eli Zaretskii <eliz@gnu.org>
+
+ * dired.c (Fdirectory_files_and_attributes, Ffile_attributes):
+ Mention w32-get-true-file-attributes in the doc strings.
+
+ * w32proc.c (syms_of_ntproc) <w32-get-true-file-attributes>: Doc fix.
+
+ * w32.c (stat): Fix test of Vw32_get_true_file_attributes against
+ the value returned by GetDriveType.
+
+2008-05-04 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * image.c [USE_MAC_IMAGE_IO] (image_load_image_io):
+ Create bitmap context in native byte order.
+
+ * macterm.c (XDrawLine, XCreatePixmapFromBitmapData) [USE_MAC_IMAGE_IO]:
+ Create bitmap context in native byte order.
+
+2008-05-03 Eli Zaretskii <eliz@gnu.org>
+
+ * dired.c (Ffile_attributes): Don't allow the device number become
+ negative.
+
+2008-05-02 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * config.in: Regenerate.
+
+ * image.c (PIX_MASK_DRAW, PIX_MASK_RETAIN) [USE_MAC_IMAGE_IO]:
+ New definitions for Image I/O support.
+ (XGetImage, XPutPixel, XGetPixel, XDestroyImage)
+ (mac_create_cg_image_from_image, x_create_x_image_and_pixmap)
+ [USE_MAC_IMAGE_IO]: Add implementations for Image I/O support.
+ (mac_data_provider_release_data, image_load_image_io)
+ [USE_MAC_IMAGE_IO]: New functions.
+ (CGImageCreateWithPNGDataProviderProcType) [MAC_OSX]: Remove typedef.
+ (MyCGImageCreateWithPNGDataProvider) [MAC_OSX]: Remove variable.
+ (init_image_func_pointer) [MAC_OSX]: Remove function.
+ (image_load_quartz2d) [MAC_OSX]: Check availability of
+ CGImageCreateWithPNGDataProvider at compile time.
+ Use lowercase `false' for boolean constant.
+ (png_load, jpeg_load, tiff_load, gif_load) [USE_MAC_IMAGE_IO]:
+ Use image_load_image_io.
+ (png_load) [!USE_MAC_IMAGE_IO && MAC_OSX]:
+ Don't check MyCGImageCreateWithPNGDataProvider.
+ (init_image) [MAC_OSX && TARGET_API_MAC_CARBON]:
+ Don't call init_image_func_pointer.
+
+ * macgui.h (Pixmap) [USE_MAC_IMAGE_IO]: New definition for Image I/O.
+
+ * macterm.c (mac_cg_color_space_rgb) [USE_CG_DRAWING]:
+ Make variable non-static.
+ (XDrawLine, XCreatePixmap, XCreatePixmapFromBitmapData, XFreePixmap)
+ [USE_MAC_IMAGE_IO]: Add implementations for Image I/O support.
+
+ * macterm.h (ARGB_TO_ULONG, ALPHA_FROM_ULONG): New macros.
+ (RED_FROM_ULONG): Mask off higher bits.
+ (mac_cg_color_space_rgb) [USE_MAC_IMAGE_IO]: New extern.
+
+ * s/darwin.h [HAVE_CARBON && HAVE_AVAILABILITYMACROS_H]:
+ Include AvailabilityMacros.h.
+ (USE_MAC_IMAGE_IO, LIBS_IMAGE) [HAVE_CARBON]: New defines.
+ (LIBS_CARBON) [HAVE_CARBON]: Use LIBS_IMAGE.
+
+2008-04-25 Dennis Gilmore <ausil@fedoraproject.org> (tiny change)
+
+ * m/sparc.h: Additional redefinitions for GNU/Linux.
+
+2008-04-23 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macterm.c (Vmac_ts_active_input_buf) [USE_MAC_TSM]: New variable.
+ (syms_of_macterm) [USE_MAC_TSM]: Defvar it.
+ (Qmouse_drag_overlay) [MAC_OSX]: New variable.
+ (syms_of_macterm) [MAC_OSX]: Intern and staticpro it.
+ (mac_get_selected_range, mac_store_buffer_text_to_unicode_chars)
+ (mac_ax_selected_text_range) [MAC_OSX]: New functions.
+ (mac_ax_number_of_characters) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]:
+ Likewise.
+
+ * mactoolbox.c (Vmac_ts_active_input_buf) [USE_MAC_TSM]: Add extern.
+ (fast_find_position, x_y_to_hpos_vpos, mac_ax_selected_text_range)
+ (mac_ax_number_of_characters): Add externs.
+ (mac_get_selected_range, mac_store_buffer_text_to_unicode_chars)
+ [USE_MAC_TSM]: Likewise.
+ (mac_handle_text_input_event) [MAC_OSX]:
+ Handle kEventTextInputOffsetToPos for no active input area case.
+ Handle kEventTextInputPosToOffset and kEventTextInputGetSelectedText.
+ (mac_handle_document_access_event)
+ [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: New function.
+ (install_application_handler) [MAC_OSX]: Register handlers for
+ kEventTextInputPosToOffset and kEventTextInputGetSelectedText.
+ (install_application_handler) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]:
+ Register mac_handle_document_access_event.
+
+ * xdisp.c (x_y_to_hpos_vpos, fast_find_position) [HAVE_CARBON]:
+ Make functions non-static.
+
+2008-04-19 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * mac.c (create_apple_event) [TARGET_API_MAC_CARBON]:
+ Make function non-static.
+ (create_apple_event_from_event_ref) [TARGET_API_MAC_CARBON]:
+ Remove function.
+ (create_apple_event_from_drag_ref) [TARGET_API_MAC_CARBON]:
+ Move to mactoolbox.c.
+ (mac_event_parameters_to_lisp) [TARGET_API_MAC_CARBON]: New function.
+
+ * macgui.h (CGFloat) [!CGFLOAT_DEFINED]: New typedef.
+ (mac_rect_make): New macro.
+
+ * macterm.c (mac_draw_image_string_atsui) [MAC_OSX]: Use CGFloat
+ instead of float.
+ (mac_draw_image_string_cg) [USE_CG_TEXT_DRAWING]: Likewise.
+ (init_cg_color, mac_draw_line, mac_draw_cg_image, XSetForeground)
+ (XSetBackground) [USE_CG_DRAWING]: Likewise.
+ (mac_draw_image_string_atsui) [MAC_OSX]: Use mac_rect_make instead of
+ CGRectMake.
+ (mac_draw_image_string_cg) [USE_CG_TEXT_DRAWING]: Likewise.
+ (mac_erase_rectangle, mac_draw_cg_image, mac_fill_rectangle)
+ (mac_set_clip_rectangles) [USE_CG_DRAWING]: Likewise.
+ (XCreatePixmap, XCreatePixmapFromBitmapData): Use Window
+ instead of WindowRef in argument type.
+ (XCreatePixmap) [!MAC_OS8]: Don't call SetPortWindowPort.
+ (mac_invert_rectangle): Use CGContextSetBlendMode if available.
+ (mac_set_clip_rectangles, mac_reset_clip_rectangles): Take argument F
+ instead of DISPLAY. All uses changed.
+ (mac_handle_size_change): Don't call SET_FRAME_GARBAGED.
+ (x_calc_absolute_position): Simplify so as not to use
+ FRAME_PIXEL_WIDTH/FRAME_PIXEL_HEIGHT.
+ (Vmac_ts_script_language_on_focus, saved_ts_script_language_on_focus)
+ [USE_MAC_TSM]: Make variables static.
+ (mac_store_event_ref_as_apple_event) [TARGET_API_MAC_CARBON]:
+ Don't use create_apple_event_from_event_ref.
+ Use mac_event_parameters_to_lisp.
+
+ * macterm.h (XCreatePixmap, XCreatePixmapFromBitmapData): Use Window
+ instead of WindowRef in argument type.
+ (create_apple_event_from_event_ref, create_apple_event_from_drag_ref)
+ [TARGET_API_MAC_CARBON]: Remove externs.
+ (create_apple_event, mac_event_parameters_to_lisp)
+ [TARGET_API_MAC_CARBON]: Add externs.
+
+ * mactoolbox.c (Vmac_ts_script_language_on_focus)
+ (saved_ts_script_language_on_focus) [USE_MAC_TSM]: Remove externs.
+ (XTread_socket) [USE_MAC_TOOLBAR]: Select window if its structure part
+ is clicked.
+ (x_activate_menubar): Remove extern for saved_menu_event_location.
+ (create_apple_event_from_drag_ref) [TARGET_API_MAC_CARBON]:
+ Move from mac.c.
+
+2008-04-12 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * alloc.c [!SYSTEM_MALLOC && !SYNC_INPUT] (uninterrupt_malloc)
+ [HAVE_GTK_AND_PTHREAD && !DOUG_LEA_MALLOC]: Don't use recursive mutex.
+
+2008-04-11 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * puresize.h (BASE_PURESIZE): Increase to 1140000.
+
+2008-04-10 Michael Albinus <michael.albinus@gmx.de>
+
+ * fileio.c (Fmake_symbolic_link): Surround code by #ifdef S_IFLNK
+ only after check for file name handler functions. Signal, when
+ native functionality is not supported.
+ (syms_of_fileio): Declare it unconditionally.
+
+2008-04-10 Jason Rumney <jasonr@gnu.org>
+
+ * w32.c (stat): When Vw32_get_true_file_attributes is Qlocal, get
+ attributes only for local files.
+
+ * w32proc.c (syms_of_ntproc): Change Vw32_get_true_file attributes
+ default to Qlocal.
+
+2008-04-06 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * Makefile.in (MAC_OBJ): Add mactoolbox.o.
+ (mactoolbox.o): New target.
+
+ * mac.c [MAC_OSX] (select_and_poll_event, sys_select):
+ Use mac_run_loop_run_once instead of CFRunLoopRunInMode.
+
+ * macfns.c (x_set_background_color, mac_window, x_create_tip_frame):
+ Use mac_set_frame_window_background instead of XSetWindowBackground.
+ (x_set_tool_bar_lines) [USE_MAC_TOOLBAR]:
+ Use mac_is_window_toolbar_visible instead of IsWindowToolbarVisible.
+ (x_set_name_internal) [TARGET_API_MAC_CARBON]: Use mac_set_window_title
+ instead of SetWindowTitleWithCFString.
+ (mac_update_proxy_icon) [TARGET_API_MAC_CARBON]: Remove BLOCK_INPUT.
+ Move function to mactoolbox.c.
+ (mac_update_title_bar) [TARGET_API_MAC_CARBON]:
+ Use mac_set_window_modified instead of SetWindowModified.
+ Add BLOCK_INPUT around mac_set_window_modified/mac_update_proxy_icon.
+ (mac_window, x_create_tip_frame): Use mac_create_frame_window.
+ (Fx_focus_frame): Use mac_front_non_floating_window instead of
+ FrontNonFloatingWindow. Use mac_activate_window instead of
+ ActivateWindow. Use mac_active_non_floating_window instead of
+ ActiveNonFloatingWindow.
+ (show_hourglass, hide_hourglass) [TARGET_API_MAC_CARBON]:
+ Use mac_show_hourglass and mac_hide_hourglass.
+ (compute_tip_xy) [TARGET_API_MAC_CARBON]: Use mac_get_global_mouse
+ instead of GetGlobalMouse.
+ (Fx_show_tip): Use mac_move_window/mac_size_window/mac_show_window
+ instead of MoveWindow/SizeWindow/ShowWindow, respectively.
+ Use mac_bring_window_to_front instead of BringToFront.
+ (Qfile_name_history) [TARGET_API_MAC_CARBON]: Move extern to
+ mactoolbox.c.
+ (Fx_file_dialog) [TARGET_API_MAC_CARBON]: Move function body to
+ mac_file_dialog in mactoolbox.c. Use mac_file_dialog.
+ (mac_nav_event_callback) [TARGET_API_MAC_CARBON]: Move function to
+ mactoolbox.c.
+
+ * macgui.h [!HAVE_CARBON]: Include Quickdraw.h instead of QuickDraw.h.
+ (XtPointer): Move typedef from macmenu.c.
+ (enum button_type): Move enum from macmenu.c.
+ (widget_value): Move typedef from macmenu.c.
+ (M_APPLE, I_ABOUT, EXTRA_STACK_ALLOC, ARGV_STRING_LIST_ID)
+ (DIALOG_LEFT_MARGIN, DIALOG_TOP_MARGIN, DIALOG_RIGHT_MARGIN)
+ (DIALOG_BOTTOM_MARGIN, DIALOG_MIN_INNER_WIDTH, DIALOG_MAX_INNER_WIDTH)
+ (DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE)
+ (DIALOG_BUTTON_BUTTON_VERTICAL_SPACE, DIALOG_BUTTON_MIN_WIDTH)
+ (DIALOG_TEXT_MIN_HEIGHT, DIALOG_TEXT_BUTTONS_VERTICAL_SPACE)
+ (DIALOG_ICON_WIDTH, DIALOG_ICON_HEIGHT, DIALOG_ICON_LEFT_MARGIN)
+ (DIALOG_ICON_TOP_MARGIN): Move defines from macmenu.c.
+ (Selection): Move typedef from macselect.c.
+ (RAM_TOO_LARGE_ALERT_ID, ABOUT_ALERT_ID) [MAC_OS8]: Move defines from
+ macterm.c.
+ (mac_set_window_title, mac_set_window_modified, mac_is_window_visible)
+ (mac_is_window_collapsed, mac_bring_window_to_front)
+ (mac_send_window_behind, mac_hide_window, mac_show_window)
+ (mac_collapse_window, mac_front_non_floating_window)
+ (mac_active_non_floating_window, mac_activate_window)
+ (mac_move_window_structure, mac_move_window, mac_size_window)
+ (mac_get_global_mouse, mac_is_window_toolbar_visible): New defines.
+
+ * macmenu.c [!TARGET_API_MAC_CARBON]: Move includes to mactoolbox.c.
+ (enum mac_menu_kind): Move enum to mactoolbox.c.
+ (min_menu_id): Move variable to mactoolbox.c.
+ (quit_dialog_event_loop) [TARGET_API_MAC_CARBON]: Likewise.
+ (DIALOG_WINDOW_RESOURCE): Move define to mactoolbox.c.
+ (DIALOG_BUTTON_COMMAND_ID_OFFSET, DIALOG_BUTTON_COMMAND_ID_P)
+ (DIALOG_BUTTON_COMMAND_ID_VALUE, DIALOG_BUTTON_MAKE_COMMAND_ID)
+ [TARGET_API_MAC_CARBON]: Likewise.
+ (XtPointer): Move typedef to macgui.h.
+ (enum button_type): Move enum to macgui.h.
+ (widget_value): Move typedef to macgui.h.
+ (DIALOG_LEFT_MARGIN, DIALOG_TOP_MARGIN, DIALOG_RIGHT_MARGIN)
+ (DIALOG_BOTTOM_MARGIN, DIALOG_MIN_INNER_WIDTH, DIALOG_MAX_INNER_WIDTH)
+ (DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE)
+ (DIALOG_BUTTON_BUTTON_VERTICAL_SPACE, DIALOG_BUTTON_MIN_WIDTH)
+ (DIALOG_TEXT_MIN_HEIGHT, DIALOG_TEXT_BUTTONS_VERTICAL_SPACE)
+ (DIALOG_ICON_WIDTH, DIALOG_ICON_HEIGHT, DIALOG_ICON_LEFT_MARGIN)
+ (DIALOG_ICON_TOP_MARGIN): Move defines to macgui.h.
+ (popup_activated_flag): Make variable non-static.
+ (x_activate_menubar, install_menu_quit_handler, pop_down_menu)
+ (add_menu_item, fill_menu, dispose_menus):
+ Move functions to mactoolbox.c.
+ (restore_show_help_function, menu_target_item_handler)
+ (install_menu_target_item_handler, mac_handle_dialog_event)
+ (install_dialog_event_handler, pop_down_dialog, create_and_show_dialog)
+ [TARGET_API_MAC_CARBON]: Likewise.
+ (menu_quit_handler) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: Likewise.
+ (mac_dialog) [!TARGET_API_MAC_CARBON]: Likewise.
+ (find_and_call_menu_selection, name_is_separator): Make function
+ non-static.
+ (Vshow_help_function, timer_check) [TARGET_API_MAC_CARBON]: Move extern
+ to mactoolbox.c.
+ (set_frame_menubar): Don't call install_menu_quit_handler.
+ (menu_item_selection): New variable.
+ (mac_menu_show): Use create_and_show_popup_menu.
+ (create_and_show_dialog) [TARGET_API_MAC_CARBON]: Don't return
+ selection but set variable menu_item_selection. All uses changed.
+ (mac_fill_menubar): Rename from fill_menubar. All uses changed.
+ Call install_menu_quit_handler. Move to mactoolbox.c.
+
+ * macselect.c [!TARGET_API_MAC_CARBON]: Don't include Scrap.h.
+ (Selection): Move typedef to macgui.h.
+ (Vselection_converter_alist, Qmac_scrap_name, Qmac_ostype)
+ (Vmac_apple_event_map, Qmac_apple_event_class, Qmac_apple_event_id):
+ Make variables non-static.
+ (Vmac_dnd_known_types) [TARGET_API_MAC_CARBON]: Likewise.
+ (mac_handle_apple_event, cleanup_all_suspended_apple_events):
+ Make functions non-static.
+ (Vmac_service_selection) [MAC_OSX]: Likewise.
+ (mac_get_selection_from_symbol, get_flavor_type_from_symbol)
+ (mac_valid_selection_target_p, mac_clear_selection)
+ (mac_get_selection_ownership_info, mac_valid_selection_value_p)
+ (mac_put_selection_value, mac_selection_has_target_p)
+ (mac_get_selection_value, mac_get_selection_target_list)
+ (init_apple_event_handler, install_drag_handler, remove_drag_handler):
+ Move functions to mactoolbox.c.
+ (mac_do_track_drag, mac_do_receive_drag) [TARGET_API_MAC_CARBON]:
+ Likewise.
+ (copy_scrap_flavor_data, mac_handle_service_event)
+ (install_service_handler) [MAC_OSX]: Likewise.
+ (syms_of_macselect) <Vmac_dnd_known_types>:
+ Use mac_dnd_default_known_types.
+
+ * macterm.c (mac_end_clip): Add argument F. All uses changed.
+ (mac_begin_cg_clip, mac_end_cg_clip): Allow null GC.
+ (mac_invert_rectangle, mac_compute_glyph_string_overhangs)
+ (mac_load_query_font): Use them instead of SetPortWindowPort.
+ (mac_clear_window) [!USE_CG_DRAWING]: Likewise.
+ (mac_draw_image_string_cg): Call CGContextSetTextMatrix.
+ (x_update_begin, x_update_end): Call mac_update_begin and
+ mac_update_end.
+ (XTframe_up_to_date): Call mac_frame_up_to_date.
+ (XTring_bell): Use mac_alert_sound_play.
+ (note_mouse_movement): Use mac_get_frame_bounds.
+ (XTmouse_position): Use mac_get_frame_mouse.
+ (x_scroll_bar_create): Use mac_create_scroll_bar.
+ (x_scroll_bar_remove): Use mac_dispose_scroll_bar.
+ (XTset_vertical_scroll_bar): Use mac_set_scroll_bar_bounds and
+ mac_redraw_scroll_bar.
+ (mac_move_window_with_gravity) [USE_MAC_TOOLBAR]: Use mac_move_window
+ instead of MoveWindow.
+ (mac_handle_size_change) [TARGET_API_MAC_CARBON]:
+ Use mac_reposition_hourglass.
+ (x_set_offset): Use mac_move_window_structure instead of
+ MoveWindowStructure.
+ (x_set_window_size): Use mac_size_window instead of SizeWindow.
+ (x_set_mouse_pixel_position) [MAC_OSX]:
+ Use mac_convert_frame_point_to_global.
+ (x_raise_frame): Use mac_bring_window_to_front instead of BringToFront.
+ (x_lower_frame): Use mac_send_window_behind instead of SendBehind.
+ (mac_handle_visibility_change): Use Window instead of WindowRef.
+ Use mac_is_window_visible/mac_is_window_collapsed instead of
+ IsWindowVisible/IsWindowCollapsed, respectively.
+ Use mac_collapse_window/mac_show_window instead of
+ CollapseWindow/ShowWindow, respectively.
+ (x_make_frame_invisible): Use mac_hide_window instead of HideWindow.
+ (x_iconify_frame): Use mac_show_window instead of ShowWindow.
+ Use mac_collapse_window instead of CollapseWindow.
+ (x_free_frame_resources): Use Window instead of WindowRef.
+ Use mac_dispose_frame_window. Clean up focus-related variables before
+ calling mac_dispose_frame_window.
+ (do_zoom_window) [MAC_OS8]: Use mac_clear_area instead of
+ mac_clear_window.
+ (mac_initialize): Use mac_toolbox_initialize instead of
+ initializing any_help_event_p and calling init_apple_event_handler,
+ init_tsm, and init_menu_bar.
+ (any_help_event_p, last_window, save_port_clip_region)
+ (read_socket_inev, saved_menu_event_location): Move variables to
+ mactoolbox.c.
+ (last_scroll_bar_part, scroll_bar_timer)
+ (scroll_bar_timer_event_posted_p) [USE_TOOLKIT_SCROLL_BARS]: Likewise.
+ (font_panel_shown_p) [USE_MAC_FONT_PANEL]: Likewise.
+ (tsm_document_id) [USE_MAC_TSM]: Likewise.
+ (mouse_region) [!TARGET_API_MAC_CARBON]: Likewise.
+ (mac_window_to_frame, DEFAULT_NUM_COLS, MIN_DOC_SIZE, MAX_DOC_SIZE):
+ Move defines to mactoolbox.c.
+ (FRAME_CG_CONTEXT) [USE_CG_DRAWING]: Likewise.
+ (SCROLL_BAR_FIRST_DELAY, SCROLL_BAR_CONTINUOUS_DELAY)
+ [USE_TOOLKIT_SCROLL_BARS]: Likewise.
+ (TOOLBAR_IDENTIFIER, TOOLBAR_ICON_ITEM_IDENTIFIER)
+ (TOOLBAR_ITEM_COMMAND_ID_OFFSET, TOOLBAR_ITEM_COMMAND_ID_P)
+ (TOOLBAR_ITEM_COMMAND_ID_VALUE, TOOLBAR_ITEM_MAKE_COMMAND_ID)
+ [USE_MAC_TOOLBAR]: Likewise.
+ (M_APPLE, I_ABOUT, EXTRA_STACK_ALLOC, ARGV_STRING_LIST_ID)
+ (RAM_TOO_LARGE_ALERT_ID, ABOUT_ALERT_ID): Move defines to macgui.h
+ (x_flush, is_emacs_window, mac_begin_clip, mac_end_clip)
+ (x_scroll_bar_handle_click, x_scroll_bar_report_motion)
+ (mac_get_window_bounds, do_window_update, is_emacs_window)
+ (do_grow_window, do_zoom_window, install_window_handler)
+ (remove_window_handler, XTread_socket, init_menu_bar): Move functions
+ to mactoolbox.c.
+ (mac_flush_display_optional, mac_begin_cg_clip, mac_end_cg_clip)
+ (mac_prepare_for_quickdraw) [USE_CG_DRAWING]: Likewise.
+ (mac_scroll_area, mac_event_to_emacs_modifiers, mac_get_mouse_btn)
+ (mac_convert_event_ref, mac_get_ideal_size, mac_store_drag_event)
+ (mac_handle_window_event, mac_handle_keyboard_event)
+ (mac_handle_command_event, mac_handle_mouse_event)
+ (install_application_handler, mac_post_mouse_moved_event)
+ [TARGET_API_MAC_CARBON]: Likewise.
+ (scroll_bar_timer_callback, install_scroll_bar_timer)
+ (set_scroll_bar_timer, control_part_code_to_scroll_bar_part)
+ (construct_scroll_bar_click, get_control_part_bounds)
+ (x_scroll_bar_handle_press, x_scroll_bar_handle_release)
+ (x_scroll_bar_handle_drag, x_set_toolkit_scroll_bar_thumb)
+ [USE_TOOLKIT_SCROLL_BARS]: Likewise.
+ (x_scroll_bar_set_handle, x_scroll_bar_note_movement)
+ [!USE_TOOLKIT_SCROLL_BARS]: Likewise.
+ (mac_handle_toolbar_event, mac_create_frame_tool_bar)
+ (update_frame_tool_bar, free_frame_tool_bar)
+ (mac_tool_bar_note_mouse_movement, mac_handle_toolbar_command_event)
+ [USE_MAC_TOOLBAR]: Likewise.
+ (mac_font_panel_visible_p, mac_handle_font_event)
+ (mac_show_hide_font_panel, mac_set_font_info_for_selection)
+ [USE_MAC_FONT_PANEL]: Likewise.
+ (mac_handle_text_input_event, init_tsm) [USE_MAC_TSM]: Likewise.
+ (do_apple_menu, mac_wait_next_event) [!TARGET_API_MAC_CARBON]: Likewise.
+ (mac_store_service_event) [MAC_OSX]: Likewise.
+ (last_mouse_glyph, last_mouse_glyph_frame, last_mouse_scroll_bar)
+ (last_mouse_movement_time, input_signal_count)
+ (mac_screen_config_changed, Qhi_command, Qtoolbar_switch_mode)
+ (Qservice, Qpaste, Qperform, keycode_to_xkeysym_table): Make variables
+ non-static.
+ (Qpanel_closed, Qselection) [USE_MAC_FONT_PANEL]: Likewise.
+ (Qtext_input, Vmac_ts_active_input_overlay, Qupdate_active_input_area)
+ (Qunicode_for_key_event, Vmac_ts_script_language_on_focus)
+ (saved_ts_script_language_on_focus) [USE_MAC_TSM]: Likewise.
+ (mac_focus_changed, note_mouse_movement, mac_focus_frame)
+ (mac_handle_origin_change, mac_handle_size_change)
+ (mac_handle_visibility_change, mac_to_emacs_modifiers)
+ (mac_mapped_modifiers, mac_get_emulated_btn, do_keystroke)
+ (mac_get_screen_info): Make functions non-static.
+ (mac_move_window_with_gravity, mac_get_window_origin_with_gravity)
+ (mac_image_spec_to_cg_image) [USE_MAC_TOOLBAR]: Likewise.
+ (mac_store_event_ref_as_apple_event) [TARGET_API_MAC_CARBON]: Likewise.
+ (Qwindow, mac_ready_for_apple_events): Move externs to mactoolbox.c.
+ (Qbefore_string) [USE_MAC_TSM]: Likewise.
+ (mac_toolbox_initialize, x_scroll_bar_report_motion, XTread_socket):
+ Add externs.
+ (mac_flush_display_optional) [USE_CG_DRAWING]: Likewise.
+ (install_drag_handler, remove_drag_handler, install_service_handler)
+ (install_menu_target_item_handler): Remove externs.
+ (XSetWindowBackground): Rename to mac_set_frame_window_background.
+ Take frame as argument instead of display and window.
+ Move to mactoolbox.c.
+ (mac_restore_keyboard_input_source, mac_save_keyboard_input_source)
+ [USE_MAC_TSM]: New functions created from mac_tsm_resume and
+ mac_tsm_suspend, respectively.
+ (mac_tsm_resume, mac_tsm_suspend) [USE_MAC_TSM]: Use them.
+ Move to mactoolbox.c.
+
+ * macterm.h (FRAME_OUTER_TO_INNER_DIFF_X, FRAME_OUTER_TO_INNER_DIFF_Y):
+ Move to mactoolbox.c.
+ (HOURGLASS_WIDTH, HOURGLASS_HEIGHT): Change to 15.
+ (Fx_selection_owner_p): Add EXFUN.
+ (install_window_handler, remove_window_handler, XSetWindowBackground):
+ Remove externs.
+ (do_apple_menu) [!TARGET_API_MAC_CARBON]: Likewise.
+ (mac_prepare_for_quickdraw) [USE_CG_DRAWING]: Likewise.
+ (x_raise_frame, x_lower_frame, mac_alert_sound_play)
+ (install_application_handler, mac_get_frame_bounds, mac_get_frame_mouse)
+ (mac_convert_frame_point_to_global, mac_set_frame_window_background)
+ (mac_update_begin mac_update_end, mac_frame_up_to_date, x_flush)
+ (mac_create_frame_window, mac_dispose_frame_window, mac_begin_clip)
+ (mac_end_clip, mac_create_scroll_bar, mac_dispose_scroll_bar)
+ (mac_set_scroll_bar_bounds, mac_redraw_scroll_bar, mac_fill_menubar)
+ (create_and_show_popup_menu, mac_get_selection_from_symbol)
+ (mac_valid_selection_target_p, mac_clear_selection)
+ (mac_get_selection_ownership_info, mac_valid_selection_value_p)
+ (mac_put_selection_value, mac_selection_has_target_p)
+ (mac_get_selection_value, mac_get_selection_target_list): Add externs.
+ (mac_update_proxy_icon, mac_show_hourglass, mac_hide_hourglass)
+ (mac_reposition_hourglass, mac_file_dialog, create_and_show_dialog)
+ (mac_dnd_default_known_types) [TARGET_API_MAC_CARBON]: Likewise.
+ (mac_run_loop_run_once) [MAC_OSX]: Likewise.
+ (mac_dialog) [!TARGET_API_MAC_CARBON]: Likewise.
+ (mac_begin_cg_clip, mac_end_cg_clip) [USE_CG_DRAWING]: Likewise.
+ (x_set_toolkit_scroll_bar_thumb) [!USE_TOOLKIT_SCROLL_BARS]: Likewise.
+ (x_scroll_bar_set_handle) [!USE_TOOLKIT_SCROLL_BARS]: Likewise.
+
+ * mactoolbox.c: New file.
+
+2008-04-05 Chong Yidong <cyd@stupidchicken.com>
+
+ * search.c (compile_pattern_1): Treat non-nil and non-string of
+ search-spaces-regexp as nil.
+
+2008-04-05 Eli Zaretskii <eliz@gnu.org>
+
+ * dired.c (Ffile_attributes) [WINDOWSNT]: Force inode be positive.
+
+2008-03-31 Chong Yidong <cyd@stupidchicken.com>
+
+ * xdisp.c (next_overlay_string): Don't set
+ overlay_strings_at_end_processed_p if we're currently reading from
+ a display string.
+
+ * fileio.c (auto_save_error_occurred): New var.
+ (auto_save_error): Set it.
+ (Fdo_auto_save): Don't overwrite the error message if an auto-save
+ error occurred.
+
+2008-03-31 Jason Rumney <jasonr@gnu.org>
+
+ * dired.c (Ffile_attributes) [WINDOWSNT]: Cast uid and gid to unsigned.
+
+2008-03-29 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * frame.h (struct frame) [MAC_OS]: New member external_tool_bar.
+ (FRAME_EXTERNAL_TOOL_BAR) [MAC_OS]: Use it.
+
+ * mac.c (xrm_get_preference_database): Remove BLOCK_INPUT.
+ [TARGET_API_MAC_CARBON] (cfdate_to_lisp): Obtain microsec value.
+ Use kCFAbsoluteTimeIntervalSince1970.
+ (wakeup_from_rne_enabled_p) [MAC_OSX]: Remove variable.
+ (ENABLE_WAKEUP_FROM_RNE, DISABLE_WAKEUP_FROM_RNE) [MAC_OSX]:
+ Remove macros.
+ [MAC_OSX] (socket_callback): Do nothing.
+ [MAC_OSX] (select_and_poll_event): Use CFRunLoopRunInMode instead of
+ ReceiveNextEvent.
+ [MAC_OSX] (sys_select): Likewise. Don't set context as argument to
+ socket_callback.
+ (mac_wakeup_from_rne) [MAC_OSX]: Do nothing.
+
+ * macfns.c (mac_window): Replace WindowPtr with WindowRef.
+ (mac_get_window_bounds): Move extern to macterm.h.
+ (compute_tip_xy) [TARGET_API_MAC_CARBON]: Use GetGlobalMouse.
+ (mac_window) [USE_MAC_TOOLBAR]: Set toolbar_win_gravity.
+ (x_set_tool_bar_lines) [USE_MAC_TOOLBAR]: Set FRAME_EXTERNAL_TOOL_BAR.
+
+ * macgui.h: Replace WindowPtr with WindowRef.
+ (USE_MAC_TOOLBAR): New define.
+ (USE_CG_DRAWING): Don't require USE_ATSUI.
+
+ * macmenu.c: Replace MenuHandle and GetMenuHandle with MenuRef and
+ GetMenuRef, respectively. Replace WindowPtr with WindowRef.
+ Replace ControlHandle with ControlRef.
+ [!TARGET_API_MAC_CARBON]: Include Quickdraw.h instead of QuickDraw.h.
+ (install_menu_quit_handler): Rename arg MENU_HANDLE to ROOT_MENU.
+ [TARGET_API_MAC_CARBON] (menu_target_item_handler): Don't call next
+ handler. Return immediately unless popup is activated.
+ [TARGET_API_MAC_CARBON] (install_menu_target_item_handler):
+ Remove argument. Install handler to application.
+ (set_frame_menubar): Don't change deep_p.
+ (mac_menu_show): Use FRAME_OUTER_TO_INNER_DIFF_X and
+ FRAME_OUTER_TO_INNER_DIFF_Y.
+ (DIALOG_BUTTON_COMMAND_ID_OFFSET, DIALOG_BUTTON_COMMAND_ID_P)
+ (DIALOG_BUTTON_COMMAND_ID_VALUE, DIALOG_BUTTON_MAKE_COMMAND_ID)
+ [HAVE_DIALOGS]: New macros.
+ [HAVE_DIALOGS] (mac_handle_dialog_event, create_and_show_dialog):
+ Use them.
+ (fill_menu) [TARGET_API_MAC_CARBON]: Use SetMenuItemHierarchicalMenu.
+ (fill_menubar) [TARGET_API_MAC_CARBON]: Use CFString.
+ (mac_dialog_modal_filter, Fx_popup_dialog) [MAC_OSX]: Put special
+ treatment for Fmessage_box, Fyes_or_no_p, and Fy_or_n_p in #if 0
+ as it is not compatible with y-or-n-p-with-timeout.
+ (timer_check) [TARGET_API_MAC_CARBON]: Add extern.
+ [TARGET_API_MAC_CARBON] (mac_handle_dialog_event): Use QuitEventLoop
+ instead of QuitAppModalLoopForWindow. Consolidate QuitEventLoop calls.
+ (pop_down_dialog) [TARGET_API_MAC_CARBON]: New function.
+ [TARGET_API_MAC_CARBON] (create_and_show_dialog): Use it for unwind.
+ Run timers during dialog popup.
+ (Fmenu_or_popup_active_p) [TARGET_API_MAC_CARBON]: Use popup_activated.
+ (quit_dialog_event_loop) [TARGET_API_MAC_CARBON]: New variable.
+ [TARGET_API_MAC_CARBON] (mac_handle_dialog_event): Set it if dialog
+ event loop should be quit.
+ [TARGET_API_MAC_CARBON] (create_and_show_dialog): Quit dialog event loop
+ if quit_dialog_event_loop is set.
+
+ * macselect.c [!TARGET_API_MAC_CARBON]: Include Scrap.h.
+ [MAC_OSX] (install_service_handler): Rename from init_service_handler.
+ All callers changed. Return OSStatus value.
+ (Selection): New typedef. Use instead of ScrapRef.
+ (mac_get_selection_from_symbol): Rename from get_scrap_from_symbol.
+ (mac_valid_selection_target_p): Rename from valid_scrap_target_type_p.
+ (mac_clear_selection): Rename from clear_scrap.
+ (get_flavor_type_from_symbol): New argument SEL and subsume function of
+ scrap_has_target_type. All uses changed.
+ (mac_get_selection_ownership_info, mac_valid_selection_value_p)
+ (mac_selection_has_target_p): New functions.
+ (mac_put_selection_value): Rename from put_scrap_string.
+ (mac_get_selection_value): Rename from get_scrap_string.
+ (mac_get_selection_target_list): Rename from get_scrap_target_type_list.
+ (put_scrap_private_timestamp, scrap_has_target_type)
+ (get_scrap_private_timestamp): Remove functions.
+ (SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP): Remove define.
+ (x_own_selection, x_get_local_selection):
+ Use mac_valid_selection_value_p.
+ (x_own_selection): Don't use put_scrap_private_timestamp.
+ Record OWNERSHIP-INFO into Vselection_alist instead.
+ (x_get_local_selection): Don't check type if request is local.
+ (Fx_selection_owner_p): Don't use get_scrap_private_timestamp.
+ Detect ownership change with OWNERSHIP-INFO in Vselection_alist instead.
+
+ * macterm.c: Replace MenuHandle and GetMenuHandle with MenuRef and
+ GetMenuRef, respectively. Replace WindowPtr with WindowRef.
+ Replace ControlHandle with ControlRef.
+ (USE_CARBON_EVENTS): Remove. Use TARGET_API_MAC_CARBON instead.
+ [MAC_OS8] (do_get_menus): Rename variable `menu_handle' to `menu'.
+ (mac_begin_cg_clip): New arg F. Call SetPortWindowPort. All callers
+ changed so as not to call SetPortWindowPort.
+ (mac_begin_cg_clip) [USE_CG_DRAWING]: Call mac_prepare_for_quickdraw.
+ (mac_draw_image_string_atsui) [USE_ATSUI]: New function created from
+ mac_draw_string_common.
+ (mac_draw_image_string_qd): Likewise.
+ (mac_draw_string_common): Use them. Add INLINE.
+ (XTmouse_position, x_scroll_bar_report_motion) [TARGET_API_MAC_CARBON]:
+ Use FRAME_OUTER_TO_INNER_DIFF_X, FRAME_OUTER_TO_INNER_DIFF_Y, and
+ GetGlobalMouse.
+ (x_set_mouse_pixel_position) [MAC_OSX]: Use FRAME_OUTER_TO_INNER_DIFF_X
+ and FRAME_OUTER_TO_INNER_DIFF_Y.
+ [TARGET_API_MAC_CARBON] (mac_handle_mouse_event): Likewise.
+ [USE_MAC_TSM] (mac_handle_text_input_event): Likewise.
+ (x_make_frame_visible) [TARGET_API_MAC_CARBON]: Move code for
+ repositioning window to mac_handle_window_event.
+ (x_make_frame_invisible) [TARGET_API_MAC_CARBON]: Move code for
+ saving window location to mac_handle_window_event.
+ [USE_MAC_FONT_PANEL] (mac_show_hide_font_panel): Install handler here.
+ (install_menu_target_item_handler): Remove argument in extern.
+ [TARGET_API_MAC_CARBON] (mac_event_to_emacs_modifiers):
+ Also accept command events.
+ (do_keystroke): New function created from XTread_socket.
+ (init_command_handler): Remove functions.
+ [TARGET_API_MAC_CARBON] (mac_handle_window_event): Reposition window
+ and save window location by kEventWindowShowing and kEventWindowHiding
+ handlers here. Don't call next handler for window state change and
+ focus events.
+ (mac_handle_keyboard_event) [TARGET_API_MAC_CARBON]: New function.
+ (install_window_handler) [TARGET_API_MAC_CARBON]: Register handlers for
+ kEventWindowShowing and kEventWindowHiding events. Move installation
+ of mouse, font, text input and menu target item handlers to
+ install_application_handler.
+ (install_application_handler) [TARGET_API_MAC_CARBON]: New function.
+ (mac_handle_cg_display_reconfig) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]:
+ New function.
+ (init_dm_notification_handler) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]:
+ Register it.
+ (XTread_socket) [TARGET_API_MAC_CARBON]:
+ Consolidate SendEventToEventTarget calls.
+ Use FRAME_OUTER_TO_INNER_DIFF_X and FRAME_OUTER_TO_INNER_DIFF_Y.
+ Move keyboard handler to mac_handle_keyboard_event.
+ (XTread_socket) [!TARGET_API_MAC_CARBON]: Use do_keystroke.
+ (mac_initialize) [TARGET_API_MAC_CARBON]: Don't call
+ init_command_handler. Call install_application_handler.
+ (x_draw_fringe_bitmap) [MAC_OSX]: Extend fringe background to scroll
+ bar gap.
+ (x_scroll_bar_create) [MAC_OSX]: Set bar->fringe_extended_p.
+ (XTset_vertical_scroll_bar) [MAC_OSX]: Put leftmost/rightmost
+ scroll bars on frame edge. Check fringe background extension.
+ Don't clear extended fringe background area.
+ (TOOLBAR_IDENTIFIER, TOOLBAR_ICON_ITEM_IDENTIFIER)
+ (TOOLBAR_ITEM_COMMAND_ID_OFFSET, TOOLBAR_ITEM_COMMAND_ID_P)
+ (TOOLBAR_ITEM_COMMAND_ID_VALUE, TOOLBAR_ITEM_MAKE_COMMAND_ID):
+ [USE_MAC_TOOLBAR]: New macros.
+ (mac_move_window_with_gravity, mac_get_window_origin_with_gravity)
+ (mac_handle_toolbar_event, mac_image_spec_to_cg_image)
+ (mac_create_frame_tool_bar, update_frame_tool_bar, free_frame_tool_bar)
+ (mac_tool_bar_note_mouse_movement, mac_handle_toolbar_command_event)
+ [USE_MAC_TOOLBAR]: New functions.
+ (mac_handle_window_event) [USE_MAC_TOOLBAR]: Reposition window
+ manually if previous repositioning has failed.
+ (mac_handle_keyboard_event): Use precomputed event kind.
+ (XTread_socket) [USE_MAC_TOOLBAR]: Handle click in structure region
+ as tool bar item click. Handle mouse movement over tool bar items.
+ (frame_highlight, frame_unhighlight): Don't call
+ ActivateControl/DeactivateControl here.
+ [USE_MAC_TOOLBAR] (free_frame_tool_bar): Suppress animation when
+ frame-notice-user-settings is non-nil.
+ [USE_MAC_FONT_PANEL] (mac_handle_font_event): Also record parameter
+ for kEventParamFMFontStyle.
+ [TARGET_API_MAC_CARBON] (mac_handle_keyboard_event): Don't check
+ mac_pass_command_to_system and mac_pass_control_to_system here.
+ (XTread_socket): Call ActivateControl/DeactivateControl here.
+ (XTread_socket) [TARGET_API_MAC_CARBON]:
+ Check mac_pass_command_to_system and mac_pass_control_to_system here.
+ [TARGET_API_MAC_CARBON] (mac_handle_window_event): Don't use invisible
+ frame as parent window for repositioning.
+
+ * macterm.h (struct scroll_bar): Rename member control_handle_low
+ and control_handle_high to control_ref_low and control_ref_high.
+ All uses changed.
+ (SCROLL_BAR_CONTROL_REF, SET_SCROLL_BAR_CONTROL_REF): Rename from
+ SCROLL_BAR_CONTROL_HANDLE and SET_SCROLL_BAR_CONTROL_HANDLE,
+ respectively. All uses changed.
+ (XCreatePixmap, XCreatePixmapFromBitmapData, XSetWindowBackground)
+ (install_window_handler, remove_window_handler): Replace WindowPtr
+ with WindowRef in externs.
+ (mac_get_window_bounds): Move extern from macfns.c.
+ (FRAME_OUTER_TO_INNER_DIFF_X, FRAME_OUTER_TO_INNER_DIFF_Y): New macros.
+ (struct mac_output) [USE_MAC_TOOLBAR]: New member toolbar_win_gravity.
+ (struct scroll_bar) [MAC_OSX]: New member fringe_extended_p.
+ (update_frame_tool_bar, free_frame_tool_bar) [USE_MAC_TOOLBAR]:
+ Add externs.
+
+ * xdisp.c (update_tool_bar, redisplay_tool_bar, redisplay_window)
+ [USE_MAC_TOOLBAR]: Sync with GTK+ tool bar display.
+
+2008-03-28 Jason Rumney <jasonr@gnu.org>
+
+ * image.c (pbm_load): Allow color values up to 65535.
+ Throw an error if max_color_idx is outside the supported range.
+ Report an error when image size is invalid.
+ Read two bytes at a time when raw images have max_color_idx above 255.
+
+2008-03-26 Alexandre Oliva <aoliva@redhat.com> (tiny change)
+
+ * regex.c (EXTEND_BUFFER): Change order of pointer addition
+ operations, to avoid having the difference between pointers
+ overflow.
+
+2008-03-26 Eli Zaretskii <eliz@gnu.org>
+
+ * w32.c (readdir): If FindFirstFile/FindNextFile return in
+ cFileName a file name that includes `?' characters, use the 8+3
+ alias in cAlternateFileName instead.
+
2008-03-26 Chong Yidong <cyd@stupidchicken.com>
* Version 22.2 released.
#ifdef HAVE_CARBON
mac = $(dot)$(dot)/mac/
-MAC_OBJ = mac.o macterm.o macfns.o macmenu.o macselect.o fontset.o fringe.o image.o
+MAC_OBJ = mac.o macterm.o macfns.o macmenu.o macselect.o fontset.o fringe.o image.o mactoolbox.o
emacsapp = $(PWD)/$(mac)Emacs.app/
emacsappsrc = ${srcdir}/../mac/Emacs.app/
#endif
filemode.o: filemode.c $(config_h)
frame.o: frame.c xterm.h window.h frame.h termhooks.h commands.h keyboard.h \
blockinput.h atimer.h systime.h buffer.h charset.h fontset.h \
- msdos.h dosfns.h dispextern.h w32term.h macterm.h $(config_h)
+ msdos.h dosfns.h dispextern.h w32term.h macterm.h macgui.h $(config_h)
fringe.o: fringe.c dispextern.h frame.h window.h buffer.h $(config_h)
fontset.o: dispextern.h fontset.h fontset.c ccl.h buffer.h charset.h frame.h \
keyboard.h $(config_h)
keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h charset.h \
commands.h frame.h window.h macros.h disptab.h keyboard.h syssignal.h \
systty.h systime.h dispextern.h syntax.h $(INTERVAL_SRC) blockinput.h \
- atimer.h xterm.h puresize.h msdos.h keymap.h w32term.h macterm.h $(config_h)
+ atimer.h xterm.h puresize.h msdos.h keymap.h w32term.h macterm.h macgui.h \
+ $(config_h)
keymap.o: keymap.c buffer.h commands.h keyboard.h termhooks.h blockinput.h \
atimer.h systime.h puresize.h charset.h intervals.h keymap.h window.h \
$(config_h)
window.o: window.c indent.h commands.h frame.h window.h buffer.h termchar.h \
termhooks.h disptab.h keyboard.h dispextern.h msdos.h composite.h \
keymap.h blockinput.h atimer.h systime.h $(INTERVAL_SRC) \
- xterm.h w32term.h macterm.h $(config_h)
-xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h coding.h \
- termchar.h frame.h window.h disptab.h termhooks.h charset.h $(config_h) \
- keyboard.h $(INTERVAL_SRC) region-cache.h xterm.h w32term.h macterm.h \
- msdos.h composite.h fontset.h blockinput.h atimer.h systime.h keymap.h
+ xterm.h w32term.h macterm.h macgui.h $(config_h)
+xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h \
+ coding.h termchar.h frame.h window.h disptab.h termhooks.h charset.h \
+ $(config_h) keyboard.h $(INTERVAL_SRC) region-cache.h xterm.h w32term.h \
+ macterm.h macgui.h msdos.h composite.h fontset.h blockinput.h atimer.h \
+ systime.h keymap.h
xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h \
- keyboard.h fontset.h w32term.h macterm.h $(INTERVAL_SRC) $(config_h)
+ keyboard.h fontset.h w32term.h macterm.h macgui.h $(INTERVAL_SRC) $(config_h)
xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
$(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
charset.h gtkutil.h $(config_h)
process.h coding.h $(config_h)
macselect.o: blockinput.h atimer.h systime.h macterm.h macgui.h frame.h \
keymap.h $(config_h)
+mactoolbox.o: blockinput.h atimer.h systime.h macterm.h macgui.h frame.h \
+ charset.h coding.h ccl.h dispextern.h fontset.h termhooks.h buffer.h \
+ window.h keyboard.h $(config_h)
${emacsapp}Contents/Resources/English.lproj:
mkdir -p $@
uninterrupt_malloc ()
{
#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef DOUG_LEA_MALLOC
pthread_mutexattr_t attr;
/* GLIBC has a faster way to do this, but lets keep it portable.
pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&alloc_mutex, &attr);
+#else /* !DOUG_LEA_MALLOC */
+ /* Some systems such as Solaris 2.6 doesn't have a recursive mutex,
+ and the bundled gmalloc.c doesn't require it. */
+ pthread_mutex_init (&alloc_mutex, NULL);
+#endif /* !DOUG_LEA_MALLOC */
#endif /* HAVE_GTK_AND_PTHREAD */
if (__free_hook != emacs_blocked_free)
/* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is
needed on ia64 too. See mach_dep.c, where it also says inline
assembler doesn't work with relevant proprietary compilers. */
-#ifdef sparc
+#ifdef __sparc__
asm ("ta 3");
#endif
/* Define to 1 if ALSA is available. */
#undef HAVE_ALSA
+/* Define to 1 if you have the <AvailabilityMacros.h> header file. */
+#undef HAVE_AVAILABILITYMACROS_H
+
/* Define to 1 if you have the `bcmp' function. */
#undef HAVE_BCMP
If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
NOSORT is useful if you plan to sort the result yourself.
ID-FORMAT specifies the preferred format of attributes uid and gid, see
-`file-attributes' for further documentation. */)
+`file-attributes' for further documentation.
+On MS-Windows, performance depends on `w32-get-true-file-attributes',
+which see. */)
(directory, full, match, nosort, id_format)
Lisp_Object directory, full, match, nosort, id_format;
{
this is a cons cell containing two integers: first the high part,
then the low 16 bits.
11. Device number. If it is larger than the Emacs integer, this is
- a cons cell, similar to the inode number. */)
+ a cons cell, similar to the inode number.
+
+On MS-Windows, performance depends on `w32-get-true-file-attributes',
+which see. */)
(filename, id_format)
Lisp_Object filename, id_format;
{
shorter than an int (e.g., `short'), GCC whines about comparison
being always false due to limited range of data type. Fix by
copying s.st_uid and s.st_gid into int variables. */
+#ifdef WINDOWSNT
+ /* Windows uses signed short for the uid and gid in the stat structure,
+ but we use an int for getuid (limited to the range 0-60000).
+ So users with uid > 32767 need their uid patched back here. */
+ uid = (unsigned short) s.st_uid;
+ gid = (unsigned short) s.st_gid;
+#else
uid = s.st_uid;
gid = s.st_gid;
+#endif
if (NILP (id_format) || EQ (id_format, Qinteger))
{
values[2] = make_fixnum_or_float (uid);
values[9] = (gid != getegid ()) ? Qt : Qnil;
#endif /* BSD4_2 (or BSD4_3) */
/* Shut up GCC warnings in FIXNUM_OVERFLOW_P below. */
+#ifdef WINDOWSNT
+ {
+ /* The bit-shuffling we do in w32.c:stat can turn on the MSB, which
+ will produce negative inode numbers. People don't like that, so
+ force a positive inode instead. */
+ unsigned short tem = s.st_ino;
+ ino = tem;
+ }
+#else
ino = s.st_ino;
+#endif
if (FIXNUM_OVERFLOW_P (ino))
/* To allow inode numbers larger than VALBITS, separate the bottom
16 bits. */
/* But keep the most common cases as integers. */
values[10] = make_number (ino);
- /* Likewise for device. */
- if (FIXNUM_OVERFLOW_P (s.st_dev))
+ /* Likewise for device, but don't let it become negative. We used
+ to use FIXNUM_OVERFLOW_P here, but that won't catch large
+ positive numbers such as 0xFFEEDDCC. */
+ if ((EMACS_INT)s.st_dev < 0
+ || (EMACS_INT)s.st_dev > MOST_POSITIVE_FIXNUM)
values[11] = Fcons (make_number (s.st_dev >> 16),
make_number (s.st_dev & 0xffff));
else
#endif /* elxsi */
-#ifdef sparc
+#ifdef __sparc__
asm (".global __start");
asm (".text");
asm ("__start:");
asm (" call __exit");
asm (" nop");
-#endif /* sparc */
+#endif /* __sparc__ */
#if __FreeBSD__ == 2
char *__progname;
}
}
- { /* Now check the text-properties. */
+ { /* Now check the text properties. */
int stickiness = text_property_stickiness (prop, position, object);
if (stickiness > 0)
return Fget_text_property (position, prop, object);
}
DEFUN ("field-string-no-properties", Ffield_string_no_properties, Sfield_string_no_properties, 0, 1, 0,
- doc: /* Return the contents of the field around POS, without text-properties.
+ doc: /* Return the contents of the field around POS, without text properties.
A field is a region of text with the same `field' property.
If POS is nil, the value of point is used for POS. */)
(pos)
void (*fatal_error_signal_hook) P_ ((void));
-#ifdef HAVE_GTK_AND_PTHREAD
-/* When compiled with GTK and running under Gnome, multiple threads meay be
- created. Keep track of our main thread to make sure signals are delivered
- to it (see syssignal.h). */
+#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
+/* When compiled with GTK and running under Gnome, or Carbon under Mac
+ OS X, multiple threads may be created. Keep track of our main
+ thread to make sure signals are delivered to it (see syssignal.h). */
pthread_t main_thread;
#endif
# endif /* not SYNC_INPUT */
#endif /* not SYSTEM_MALLOC */
-#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
main_thread = pthread_self ();
-#endif /* HAVE_GTK_AND_PTHREAD */
+#endif /* FORWARD_SIGNAL_TO_MAIN_THREAD */
#if defined (MSDOS) || defined (WINDOWSNT)
/* We do all file input/output as binary files. When we need to translate
When a handler handles an error, control returns to the `condition-case'
and it executes the handler's BODY...
-with VAR bound to (SIGNALED-CONDITIONS . SIGNAL-DATA) from the error.
+with VAR bound to (ERROR-SYMBOL . SIGNAL-DATA) from the error.
(If VAR is nil, the handler can't access that information.)
Then the value of the last BODY form is returned from the `condition-case'
expression.
a new file with the same mode as the original */
int auto_save_mode_bits;
+/* Set by auto_save_1 if an error occurred during the last auto-save. */
+int auto_save_error_occurred;
+
/* The symbol bound to coding-system-for-read when
insert-file-contents is called for recovering a file. This is not
an actual coding system name, but just an indicator to tell
/* File name in which we write a list of all our auto save files. */
Lisp_Object Vauto_save_list_file_name;
+/* Whether or not files are auto-saved into themselves. */
+Lisp_Object Vauto_save_visited_file_name;
+
/* Function to call to read a file name. */
Lisp_Object Vread_file_name_function;
int length;
Lisp_Object handler, result;
int multibyte;
+ Lisp_Object hdir;
CHECK_STRING (name);
nm = SDATA (name);
multibyte = STRING_MULTIBYTE (name);
-#ifdef DOS_NT
- /* We will force directory separators to be either all \ or /, so make
- a local copy to modify, even if there ends up being no change. */
+ /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */
nm = strcpy (alloca (strlen (nm) + 1), nm);
+#ifdef DOS_NT
/* Note if special escape prefix is present, but remove for now. */
if (nm[0] == '/' && nm[1] == ':')
{
}
return name;
#else /* not DOS_NT */
- if (nm == SDATA (name))
+ if (strcmp (nm, SDATA (name)) == 0)
return name;
return make_specified_string (nm, -1, strlen (nm), multibyte);
#endif /* not DOS_NT */
#endif /* VMS */
|| nm[1] == 0) /* ~ by itself */
{
+ Lisp_Object tem;
+
if (!(newdir = (unsigned char *) egetenv ("HOME")))
newdir = (unsigned char *) "";
nm++;
+ /* egetenv may return a unibyte string, which will bite us since
+ we expect the directory to be multibyte. */
+ tem = build_string (newdir);
+ if (!STRING_MULTIBYTE (tem))
+ {
+ hdir = DECODE_FILE (tem);
+ newdir = SDATA (hdir);
+ }
#ifdef DOS_NT
collapse_newdir = 0;
#endif
return Qnil;
}
-#ifdef S_IFLNK
DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
"FMake symbolic link to file: \nGMake symbolic link to file %s: \np",
doc: /* Make a symbolic link to FILENAME, named LINKNAME.
RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
linkname, ok_if_already_exists));
+#ifdef S_IFLNK
encoded_filename = ENCODE_FILE (filename);
encoded_linkname = ENCODE_FILE (linkname);
}
UNGCPRO;
return Qnil;
-}
+
+#else
+ UNGCPRO;
+ xsignal1 (Qfile_error, build_string ("Symbolic links are not supported"));
+
#endif /* S_IFLNK */
+}
#ifdef VMS
char *msgbuf;
USE_SAFE_ALLOCA;
+ auto_save_error_occurred = 1;
+
ring_bell ();
args[0] = build_string ("Auto-saving %s: %s");
}
return
- Fwrite_region (Qnil, Qnil,
- current_buffer->auto_save_file_name,
- Qnil, Qlambda, Qnil, Qnil);
+ Fwrite_region (Qnil, Qnil, current_buffer->auto_save_file_name, Qnil,
+ NILP (Vauto_save_visited_file_name) ? Qlambda : Qt,
+ Qnil, Qnil);
}
static Lisp_Object
make_number (minibuffer_auto_raise));
minibuffer_auto_raise = 0;
auto_saving = 1;
+ auto_save_error_occurred = 0;
/* On first pass, save all files that don't have handlers.
On second pass, save all files that do have handlers.
sit_for (make_number (1), 0, 0);
restore_message ();
}
- else
- /* If we displayed a message and then restored a state
+ else if (!auto_save_error_occurred)
+ /* Don't overwrite the error message if an error occurred.
+ If we displayed a message and then restored a state
with no message, leave a "done" message on the screen. */
message1 ("Auto-saving...done");
}
a non-nil value. */);
Vauto_save_list_file_name = Qnil;
+ DEFVAR_LISP ("auto-save-visited-file-name", &Vauto_save_visited_file_name,
+ doc: /* Non-nil says auto-save a buffer in the file it is visiting, when practical.
+Normally auto-save files are written under other names. */);
+ Vauto_save_visited_file_name = Qnil;
+
#ifdef HAVE_FSYNC
DEFVAR_BOOL ("write-region-inhibit-fsync", &write_region_inhibit_fsync,
doc: /* *Non-nil means don't call fsync in `write-region'.
defsubr (&Sdelete_file);
defsubr (&Srename_file);
defsubr (&Sadd_name_to_file);
-#ifdef S_IFLNK
defsubr (&Smake_symbolic_link);
-#endif /* S_IFLNK */
#ifdef VMS
defsubr (&Sdefine_logical_name);
#endif /* VMS */
The value of frame parameter FOO can also be accessed
as a frame-local binding for the variable FOO, if you have
-enabled such bindings for that variable with `make-variable-frame-local'. */)
+enabled such bindings for that variable with `make-variable-frame-local'.
+Note that this functionality is obsolete as of Emacs 22.2, and its
+use is not recommended. Explicitly check for a frame-parameter instead. */)
(frame, alist)
Lisp_Object frame, alist;
{
be used for output. */
unsigned glyphs_initialized_p : 1;
-#if defined (USE_GTK)
+#if defined (USE_GTK) || defined (MAC_OS)
/* Nonzero means using a tool bar that comes from the toolkit. */
int external_tool_bar;
#endif
/* Nonzero if this frame should display a tool bar
in a way that does not use any text lines. */
-#if defined (USE_GTK)
+#if defined (USE_GTK) || defined (MAC_OS)
#define FRAME_EXTERNAL_TOOL_BAR(f) (f)->external_tool_bar
#else
#define FRAME_EXTERNAL_TOOL_BAR(f) 0
WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
indicating the positioning of the bitmap relative to the rows where it
-is used; the default is to center the bitmap. Fourth arg may also be a
+is used; the default is to center the bitmap. Fifth arg may also be a
list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
should be repeated.
If BITMAP already exists, the existing definition is replaced. */)
static long offset;
# if !defined(VMS) && !defined(sgi) && !defined(__linux__)
-static struct nlist nl[2];
+static struct nlist name_list[2];
# endif /* Not VMS or sgi */
# ifdef SUNOS_5
{
# ifndef sgi
# ifndef NLIST_STRUCT
- strcpy (nl[0].n_name, LDAV_SYMBOL);
- strcpy (nl[1].n_name, "");
+ strcpy (name_list[0].n_name, LDAV_SYMBOL);
+ strcpy (name_list[1].n_name, "");
# else /* NLIST_STRUCT */
# ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME
- nl[0].n_un.n_name = LDAV_SYMBOL;
- nl[1].n_un.n_name = 0;
+ name_list[0].n_un.n_name = LDAV_SYMBOL;
+ name_list[1].n_un.n_name = 0;
# else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
- nl[0].n_name = LDAV_SYMBOL;
- nl[1].n_name = 0;
+ name_list[0].n_name = LDAV_SYMBOL;
+ name_list[1].n_name = 0;
# endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
# endif /* NLIST_STRUCT */
# ifndef SUNOS_5
if (
# if !(defined (_AIX) && !defined (ps2))
- nlist (KERNEL_FILE, nl)
+ nlist (KERNEL_FILE, name_list)
# else /* _AIX */
- knlist (nl, 1, sizeof (nl[0]))
+ knlist (name_list, 1, sizeof (name_list[0]))
# endif
>= 0)
- /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i. */
+ /* Omit "&& name_list[0].n_type != 0 " -- it breaks on Sun386i. */
{
# ifdef FIXUP_KERNEL_SYMBOL_ADDR
- FIXUP_KERNEL_SYMBOL_ADDR (nl);
+ FIXUP_KERNEL_SYMBOL_ADDR (name_list);
# endif
- offset = nl[0].n_value;
+ offset = name_list[0].n_value;
}
# endif /* !SUNOS_5 */
# else /* sgi */
if (kd != 0)
{
/* nlist the currently running kernel. */
- kvm_nlist (kd, nl);
- offset = nl[0].n_value;
+ kvm_nlist (kd, name_list);
+ offset = name_list[0].n_value;
getloadavg_initialized = 1;
}
# endif /* SUNOS_5 */
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
-#include "config.h"
+#include <config.h>
#ifdef USE_GTK
#include <string.h>
return w;
}
-/* Callback called when keyboard traversal (started by x-menu-bar-open) ends.
- WMENU is the menu for which traversal has been done. DATA points to the
- frame for WMENU. We must release grabs, some bad interaction between GTK
- and Emacs makes the menus keep the grabs. */
-
-static void
-menu_nav_ended (wmenu, data)
- GtkMenuShell *wmenu;
- gpointer data;
-{
- FRAME_PTR f = (FRAME_PTR) data;
-
- if (FRAME_X_OUTPUT (f)->menubar_widget)
- {
- GtkMenuShell *w = GTK_MENU_SHELL (FRAME_X_OUTPUT (f)->menubar_widget);
- Display *dpy = FRAME_X_DISPLAY (f);
-
- BLOCK_INPUT;
- gtk_menu_shell_deactivate (w);
- gtk_menu_shell_deselect (w);
-
- XUngrabKeyboard (dpy, CurrentTime);
- XUngrabPointer (dpy, CurrentTime);
- UNBLOCK_INPUT;
- }
-}
-
-
static GtkWidget *create_menus P_ ((widget_value *, FRAME_PTR, GCallback,
GCallback, GCallback, int, int, int,
GtkWidget *, xg_menu_cb_data *, char *));
}
else wmenu = gtk_menu_bar_new ();
- /* Fix up grabs after keyboard traversal ends. */
- g_signal_connect (G_OBJECT (wmenu),
- "selection-done",
- G_CALLBACK (menu_nav_ended),
- f);
-
/* Put cl_data on the top menu for easier access. */
cl_data = make_cl_data (cl_data, f, highlight_cb);
g_object_set_data (G_OBJECT (wmenu), XG_FRAME_DATA, (gpointer)cl_data);
static void
xg_update_menubar (menubar, f, list, iter, pos, val,
- select_cb, highlight_cb, cl_data)
+ select_cb, deactivate_cb, highlight_cb, cl_data)
GtkWidget *menubar;
FRAME_PTR f;
GList **list;
int pos;
widget_value *val;
GCallback select_cb;
+ GCallback deactivate_cb;
GCallback highlight_cb;
xg_menu_cb_data *cl_data;
{
else if (! iter && val)
{
/* Item(s) added. Add all new items in one call. */
- create_menus (val, f, select_cb, 0, highlight_cb,
+ create_menus (val, f, select_cb, deactivate_cb, highlight_cb,
0, 1, 0, menubar, cl_data, 0);
/* All updated. */
/* Create a possibly empty submenu for menu bar items, since some
themes don't highlight items correctly without it. */
GtkWidget *submenu = create_menus (NULL, f,
- select_cb, NULL, highlight_cb,
+ select_cb, deactivate_cb,
+ highlight_cb,
0, 0, 0, 0, cl_data, 0);
gtk_widget_set_name (w, MENU_ITEM_NAME);
gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), w, pos);
/* Update the rest of the menu bar. */
xg_update_menubar (menubar, f, list, iter, pos, val,
- select_cb, highlight_cb, cl_data);
+ select_cb, deactivate_cb, highlight_cb, cl_data);
}
/* Update the menu item W so it corresponds to VAL.
XG_FRAME_DATA);
xg_update_menubar (menubar, f, &list, list, 0, val->contents,
- select_cb, highlight_cb, cl_data);
+ select_cb, deactivate_cb, highlight_cb, cl_data);
if (deep_p)
{
#define RGB_PIXEL_COLOR unsigned long
+#if USE_MAC_IMAGE_IO
+#define PIX_MASK_DRAW 255
+#define PIX_MASK_RETAIN 0
+#else
/* A black pixel in a mask bitmap/pixmap means ``draw a source
pixel''. A white pixel means ``retain the current pixel''. */
#define PIX_MASK_DRAW RGB_TO_ULONG(0,0,0)
#define PIX_MASK_RETAIN RGB_TO_ULONG(255,255,255)
+#endif
#define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
#define x_defined_color mac_defined_color
unsigned long plane_mask; /* not used */
int format; /* not used */
{
+#if !USE_MAC_IMAGE_IO
#if GLYPH_DEBUG
xassert (x == 0 && y == 0);
{
#endif
LockPixels (GetGWorldPixMap (pixmap));
+#endif
return pixmap;
}
int x, y;
unsigned long pixel;
{
+#if USE_MAC_IMAGE_IO
+ if (ximage->bits_per_pixel == 32)
+ ((unsigned int *)(ximage->data + y * ximage->bytes_per_line))[x] = pixel;
+ else
+ ((unsigned char *)(ximage->data + y * ximage->bytes_per_line))[x] = pixel;
+#else
PixMapHandle pixmap = GetGWorldPixMap (ximage);
short depth = GetPixDepth (pixmap);
SetGWorld (old_port, old_gdh);
}
+#endif
}
static unsigned long
XImagePtr ximage;
int x, y;
{
+#if USE_MAC_IMAGE_IO
+ if (ximage->bits_per_pixel == 32)
+ return ((unsigned int *)(ximage->data + y * ximage->bytes_per_line))[x];
+ else
+ return ((unsigned char *)(ximage->data + y * ximage->bytes_per_line))[x];
+#else
PixMapHandle pixmap = GetGWorldPixMap (ximage);
short depth = GetPixDepth (pixmap);
SetGWorld (old_port, old_gdh);
return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8);
}
+#endif
}
static void
XDestroyImage (ximg)
XImagePtr ximg;
{
+#if !USE_MAC_IMAGE_IO
UnlockPixels (GetGWorldPixMap (ximg));
+#endif
}
#if USE_CG_DRAWING
+#if USE_MAC_IMAGE_IO
+void
+mac_data_provider_release_data (info, data, size)
+ void *info;
+ const void *data;
+ size_t size;
+{
+ xfree ((void *)data);
+}
+#endif
+
static CGImageRef
mac_create_cg_image_from_image (f, img)
struct frame *f;
struct image *img;
{
+#if USE_MAC_IMAGE_IO
+ XImagePtr ximg = img->pixmap;
+ CGDataProviderRef provider;
+ CGImageRef result;
+
+ if (img->mask)
+ {
+ int x, y;
+ unsigned long color, alpha;
+
+ for (y = 0; y < ximg->height; y++)
+ for (x = 0; x < ximg->width; x++)
+ {
+ color = XGetPixel (ximg, x, y);
+ alpha = XGetPixel (img->mask, x, y);
+ XPutPixel (ximg, x, y,
+ ARGB_TO_ULONG (alpha,
+ RED_FROM_ULONG (color)
+ * alpha / PIX_MASK_DRAW,
+ GREEN_FROM_ULONG (color)
+ * alpha / PIX_MASK_DRAW,
+ BLUE_FROM_ULONG (color)
+ * alpha / PIX_MASK_DRAW));
+ }
+ xfree (img->mask->data);
+ img->mask->data = NULL;
+ }
+ BLOCK_INPUT;
+ provider = CGDataProviderCreateWithData (NULL, ximg->data,
+ ximg->bytes_per_line * ximg->height,
+ mac_data_provider_release_data);
+ ximg->data = NULL;
+ result = CGImageCreate (ximg->width, ximg->height, 8, 32,
+ ximg->bytes_per_line, mac_cg_color_space_rgb,
+ ((img->mask ? kCGImageAlphaPremultipliedFirst
+ : kCGImageAlphaNoneSkipFirst)
+ | kCGBitmapByteOrder32Host),
+ provider, NULL, 0, kCGRenderingIntentDefault);
+ CGDataProviderRelease (provider);
+ UNBLOCK_INPUT;
+
+ return result;
+#else
Pixmap mask;
CGImageRef result = NULL;
UNBLOCK_INPUT;
return result;
+#endif
}
#endif /* USE_CG_DRAWING */
#endif /* MAC_OS */
return 0;
}
+#if !USE_MAC_IMAGE_IO
LockPixels (GetGWorldPixMap (*pixmap));
+#endif
*ximg = *pixmap;
return 1;
MAC Image Load Functions
***********************************************************************/
+#if USE_MAC_IMAGE_IO
+static int
+image_load_image_io (f, img, type)
+ struct frame *f;
+ struct image *img;
+ CFStringRef type;
+{
+ CFDictionaryRef options, src_props = NULL, props = NULL;
+ CFStringRef keys[2];
+ CFTypeRef values[2];
+ Lisp_Object specified_file, specified_data;
+ CGImageSourceRef source = NULL;
+ size_t count;
+ CGImageRef image = NULL;
+ int loop_count = -1;
+ double delay_time = -1.0;
+ int width, height;
+ XImagePtr ximg = NULL;
+ CGContextRef context;
+ CGRect rectangle;
+ int has_alpha_p, gif_p;
+
+ gif_p = UTTypeEqual (type, kUTTypeGIF);
+
+ keys[0] = kCGImageSourceTypeIdentifierHint;
+ values[0] = (CFTypeRef) type;
+ keys[1] = kCGImageSourceShouldCache;
+ values[1] = (CFTypeRef) kCFBooleanFalse;
+ options = CFDictionaryCreate (NULL, (const void **) keys,
+ (const void **) values,
+ sizeof (keys) / sizeof (keys[0]),
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ if (options == NULL)
+ {
+ image_error ("Error creating options for image `%s'", img->spec, Qnil);
+ return 0;
+ }
+
+ /* Open the file. */
+ specified_file = image_spec_value (img->spec, QCfile, NULL);
+ specified_data = image_spec_value (img->spec, QCdata, NULL);
+
+ if (NILP (specified_data))
+ {
+ Lisp_Object file;
+ CFStringRef path;
+ CFURLRef url;
+
+ file = x_find_image_file (specified_file);
+ if (!STRINGP (file))
+ {
+ image_error ("Cannot find image file `%s'", specified_file, Qnil);
+ return 0;
+ }
+ path = cfstring_create_with_utf8_cstring (SDATA (file));
+ if (path)
+ {
+ url = CFURLCreateWithFileSystemPath (NULL, path,
+ kCFURLPOSIXPathStyle, 0);
+ CFRelease (path);
+ if (url)
+ {
+ source = CGImageSourceCreateWithURL (url, NULL);
+ CFRelease (url);
+ }
+ }
+ }
+ else
+ {
+ CFDataRef data = CFDataCreate (NULL, SDATA (specified_data),
+ SBYTES (specified_data));
+
+ if (data)
+ {
+ source = CGImageSourceCreateWithData (data, options);
+ CFRelease (data);
+ }
+ }
+ CFRelease (options);
+
+ if (source)
+ {
+ CFStringRef real_type = CGImageSourceGetType (source);
+
+ if (real_type && UTTypeEqual (type, real_type))
+ src_props = CGImageSourceCopyProperties (source, NULL);
+ if (src_props)
+ {
+ EMACS_INT ino = 0;
+
+ count = CGImageSourceGetCount (source);
+ if (gif_p)
+ {
+ Lisp_Object image = image_spec_value (img->spec, QCindex, NULL);
+
+ if (INTEGERP (image))
+ ino = XFASTINT (image);
+ }
+ if (ino >= 0 && ino < count)
+ {
+ props = CGImageSourceCopyPropertiesAtIndex (source, ino, NULL);
+ if (props)
+ image = CGImageSourceCreateImageAtIndex (source, ino, NULL);
+ }
+ }
+ CFRelease (source);
+ }
+
+ if (image == NULL)
+ {
+ if (src_props)
+ CFRelease (src_props);
+ if (props)
+ CFRelease (props);
+ image_error ("Error reading image `%s'", img->spec, Qnil);
+ return 0;
+ }
+ else
+ {
+ CFBooleanRef boolean;
+
+ if (CFDictionaryGetValueIfPresent (props, kCGImagePropertyHasAlpha,
+ (const void **) &boolean))
+ has_alpha_p = CFBooleanGetValue (boolean);
+ if (gif_p)
+ {
+ CFDictionaryRef dict;
+ CFNumberRef number;
+
+ dict = CFDictionaryGetValue (src_props,
+ kCGImagePropertyGIFDictionary);
+ if (dict
+ && CFDictionaryGetValueIfPresent (dict,
+ kCGImagePropertyGIFLoopCount,
+ (const void **) &number))
+ CFNumberGetValue (number, kCFNumberIntType, &loop_count);
+
+ dict = CFDictionaryGetValue (props, kCGImagePropertyGIFDictionary);
+ if (dict
+ && CFDictionaryGetValueIfPresent (dict,
+ kCGImagePropertyGIFDelayTime,
+ (const void **) &number))
+ CFNumberGetValue (number, kCFNumberDoubleType, &delay_time);
+ }
+ CFRelease (src_props);
+ CFRelease (props);
+ }
+
+ width = img->width = CGImageGetWidth (image);
+ height = img->height = CGImageGetHeight (image);
+
+ if (!check_image_size (f, width, height))
+ {
+ CGImageRelease (image);
+ image_error ("Invalid image size", Qnil, Qnil);
+ return 0;
+ }
+
+ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
+ {
+ CGImageRelease (image);
+ image_error ("Out of memory (%s)", img->spec, Qnil);
+ return 0;
+ }
+ rectangle = CGRectMake (0, 0, width, height);
+
+ context = CGBitmapContextCreate (ximg->data, ximg->width, ximg->height, 8,
+ ximg->bytes_per_line,
+ mac_cg_color_space_rgb,
+ kCGImageAlphaNoneSkipFirst
+ | kCGBitmapByteOrder32Host);
+ if (has_alpha_p)
+ {
+ Lisp_Object specified_bg;
+ XColor color;
+
+ specified_bg = image_spec_value (img->spec, QCbackground, NULL);
+ if (!STRINGP (specified_bg)
+ || !mac_defined_color (f, SDATA (specified_bg), &color, 0))
+ {
+ color.pixel = FRAME_BACKGROUND_PIXEL (f);
+ color.red = RED16_FROM_ULONG (color.pixel);
+ color.green = GREEN16_FROM_ULONG (color.pixel);
+ color.blue = BLUE16_FROM_ULONG (color.pixel);
+ }
+ CGContextSetRGBFillColor (context, color.red / 65535.0,
+ color.green / 65535.0,
+ color.blue / 65535.0, 1.0);
+ CGContextFillRect (context, rectangle);
+ }
+ CGContextDrawImage (context, rectangle, image);
+ CGContextRelease (context);
+ CGImageRelease (image);
+
+ /* Save GIF image extension data for `image-extension-data'.
+ Format is (count IMAGES
+ 0xff "NETSCAPE2.0" 0x00 DATA_SUB_BLOCK_FOR_LOOP_COUNT
+ 0xf9 GRAPHIC_CONTROL_EXTENSION_BLOCK). */
+ if (gif_p)
+ {
+ img->data.lisp_val = Qnil;
+ if (delay_time >= 0)
+ {
+ Lisp_Object gce = make_uninit_string (4);
+ int centisec = delay_time * 100.0 + 0.5;
+
+ /* Fill the delay time field. */
+ SSET (gce, 1, centisec & 0xff);
+ SSET (gce, 2, (centisec >> 8) & 0xff);
+ /* We don't know about other fields. */
+ SSET (gce, 0, 0);
+ SSET (gce, 3, 0);
+ img->data.lisp_val = Fcons (make_number (0xf9),
+ Fcons (gce,
+ img->data.lisp_val));
+ }
+ if (loop_count >= 0)
+ {
+ Lisp_Object data_sub_block = make_uninit_string (3);
+
+ SSET (data_sub_block, 0, 0x01);
+ SSET (data_sub_block, 1, loop_count & 0xff);
+ SSET (data_sub_block, 2, (loop_count >> 8) & 0xff);
+ img->data.lisp_val = Fcons (make_number (0),
+ Fcons (data_sub_block,
+ img->data.lisp_val));
+ img->data.lisp_val = Fcons (make_number (0xff),
+ Fcons (build_string ("NETSCAPE2.0"),
+ img->data.lisp_val));
+ }
+ if (count > 1)
+ img->data.lisp_val = Fcons (Qcount,
+ Fcons (make_number (count),
+ img->data.lisp_val));
+ }
+
+ /* Maybe fill in the background field while we have ximg handy. */
+ if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+ IMAGE_BACKGROUND (img, f, ximg);
+
+ /* Put the image into the pixmap. */
+ x_put_x_image (f, ximg, img->pixmap, width, height);
+ x_destroy_x_image (ximg);
+ return 1;
+}
+#else /* !USE_MAC_IMAGE_IO */
static int image_load_quicktime P_ ((struct frame *, struct image *img,
OSType));
#ifdef MAC_OSX
#ifdef MAC_OSX
-/* Load a PNG/JPEG image using Quartz 2D decoding routines.
- CGImageCreateWithPNGDataProvider is provided after Mac OS X 10.2.
- So don't use this function directly but determine at runtime
- whether it exists. */
-typedef CGImageRef (*CGImageCreateWithPNGDataProviderProcType)
- (CGDataProviderRef, const float [], bool, CGColorRenderingIntent);
-static CGImageCreateWithPNGDataProviderProcType MyCGImageCreateWithPNGDataProvider;
-
-
-static void
-init_image_func_pointer ()
-{
- if (NSIsSymbolNameDefined ("_CGImageCreateWithPNGDataProvider"))
- {
- MyCGImageCreateWithPNGDataProvider
- = (CGImageCreateWithPNGDataProviderProcType)
- NSAddressOfSymbol (NSLookupAndBindSymbol
- ("_CGImageCreateWithPNGDataProvider"));
- }
- else
- MyCGImageCreateWithPNGDataProvider = NULL;
-}
-
-
static int
image_load_quartz2d (f, img, png_p)
struct frame *f;
source = CGDataProviderCreateWithData (NULL, SDATA (specified_data),
SBYTES (specified_data), NULL);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
if (png_p)
- image = (*MyCGImageCreateWithPNGDataProvider) (source, NULL, FALSE,
- kCGRenderingIntentDefault);
+ image = CGImageCreateWithPNGDataProvider (source, NULL, false,
+ kCGRenderingIntentDefault);
else
- image = CGImageCreateWithJPEGDataProvider (source, NULL, FALSE,
+#endif
+ image = CGImageCreateWithJPEGDataProvider (source, NULL, false,
kCGRenderingIntentDefault);
CGDataProviderRelease (source);
return 1;
}
#endif
+#endif /* !USE_MAC_IMAGE_IO */
#endif /* MAC_OS */
if (isalpha (c) || c == '_' || c == '-' || c == '+')
{
*beg = *s - 1;
- while (*s < end &&
- (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+'))
+ while (*s < end
+ && (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+'))
++*s;
*len = *s - *beg;
return XPM_TK_IDENT;
if (type != PBM_MONO)
{
max_color_idx = pbm_scan_number (&p, end);
- if (raw_p && max_color_idx > 255)
- max_color_idx = 255;
+ if (max_color_idx > 65535 || max_color_idx < 0)
+ {
+ image_error ("Unsupported maximum PBM color value", Qnil, Qnil);
+ goto error;
+ }
}
- if (!check_image_size (f, width, height)
- || (type != PBM_MONO && max_color_idx < 0))
- goto error;
+ if (!check_image_size (f, width, height))
+ {
+ image_error ("Invalid image size", Qnil, Qnil);
+ goto error;
+ }
if (!x_create_x_image_and_pixmap (f, width, height, 0,
&ximg, &img->pixmap))
}
else
{
- if (raw_p
- && ((type == PBM_GRAY)
- ? (p + height * width > end)
- : (p + 3 * height * width > end)))
+ int expected_size = height * width;
+ if (max_color_idx > 255)
+ expected_size *= 2;
+ if (type == PBM_COLOR)
+ expected_size *= 3;
+
+ if (raw_p && p + expected_size > end)
{
x_destroy_x_image (ximg);
x_clear_image (f, img);
{
int r, g, b;
- if (type == PBM_GRAY)
- r = g = b = raw_p ? *p++ : pbm_scan_number (&p, end);
+ if (type == PBM_GRAY && raw_p)
+ {
+ r = g = b = *p++;
+ if (max_color_idx > 255)
+ r = g = b = r * 256 + *p++;
+ }
+ else if (type == PBM_GRAY)
+ r = g = b = pbm_scan_number (&p, end);
else if (raw_p)
{
r = *p++;
+ if (max_color_idx > 255)
+ r = r * 256 + *p++;
g = *p++;
+ if (max_color_idx > 255)
+ g = g * 256 + *p++;
b = *p++;
+ if (max_color_idx > 255)
+ b = b * 256 + *p++;
}
else
{
png_byte channels;
png_uint_32 row_bytes;
int transparent_p;
- double screen_gamma;
struct png_memory_storage tbr; /* Data to be read */
/* Find out what file to load. */
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
fn_png_set_gray_to_rgb (png_ptr);
- screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2);
-
-#if 0 /* Avoid double gamma correction for PNG images. */
- { /* Tell the PNG lib to handle gamma correction for us. */
- int intent;
- double image_gamma;
-#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
- if (png_get_sRGB (png_ptr, info_ptr, &intent))
- /* The libpng documentation says this is right in this case. */
- png_set_gamma (png_ptr, screen_gamma, 0.45455);
- else
-#endif
- if (png_get_gAMA (png_ptr, info_ptr, &image_gamma))
- /* Image contains gamma information. */
- png_set_gamma (png_ptr, screen_gamma, image_gamma);
- else
- /* Use the standard default for the image gamma. */
- png_set_gamma (png_ptr, screen_gamma, 0.45455);
- }
-#endif /* if 0 */
-
/* Handle alpha channel by combining the image with a background
color. Do this only if a real alpha channel is supplied. For
simple transparency, we prefer a clipping mask. */
png_color_16 *image_bg;
Lisp_Object specified_bg
= image_spec_value (img->spec, QCbackground, NULL);
+ int shift = (bit_depth == 16) ? 0 : 8;
if (STRINGP (specified_bg))
/* The user specified `:background', use that. */
png_color_16 user_bg;
bzero (&user_bg, sizeof user_bg);
- user_bg.red = color.red >> 8;
- user_bg.green = color.green >> 8;
- user_bg.blue = color.blue >> 8;
+ user_bg.red = color.red >> shift;
+ user_bg.green = color.green >> shift;
+ user_bg.blue = color.blue >> shift;
fn_png_set_background (png_ptr, &user_bg,
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
}
}
- /* The commented-out code checked if the png specifies a default
- background color, and uses that. Since we use the current
- frame background, it is OK for us to ignore this.
-
- else if (fn_png_get_bKGD (png_ptr, info_ptr, &image_bg))
- fn_png_set_background (png_ptr, image_bg,
- PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
- */
else
{
- /* Image does not contain a background color with which
- to combine the image data via an alpha channel. Use
- the frame's background instead. */
+ /* We use the current frame background, ignoring any default
+ background color set by the image. */
#ifdef HAVE_X_WINDOWS
XColor color;
png_color_16 frame_background;
x_query_color (f, &color);
bzero (&frame_background, sizeof frame_background);
- frame_background.red = color.red >> 8;
- frame_background.green = color.green >> 8;
- frame_background.blue = color.blue >> 8;
+ frame_background.red = color.red >> shift;
+ frame_background.green = color.green >> shift;
+ frame_background.blue = color.blue >> shift;
#endif /* HAVE_X_WINDOWS */
#ifdef HAVE_NTGUI
struct frame *f;
struct image *img;
{
-#ifdef MAC_OSX
- if (MyCGImageCreateWithPNGDataProvider)
- return image_load_quartz2d (f, img, 1);
- else
+#if USE_MAC_IMAGE_IO
+ return image_load_image_io (f, img, kUTTypePNG);
+#elif MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ return image_load_quartz2d (f, img, 1);
+#else
+ return image_load_quicktime (f, img, kQTFileTypePNG);
#endif
- return image_load_quicktime (f, img, kQTFileTypePNG);
}
#endif /* MAC_OS */
struct frame *f;
struct image *img;
{
-#ifdef MAC_OSX
+#if USE_MAC_IMAGE_IO
+ return image_load_image_io (f, img, kUTTypeJPEG);
+#elif defined (MAC_OSX)
return image_load_quartz2d (f, img, 0);
#else
return image_load_quicktime (f, img, kQTFileTypeJPEG);
struct frame *f;
struct image *img;
{
+#if USE_MAC_IMAGE_IO
+ return image_load_image_io (f, img, kUTTypeTIFF);
+#else
return image_load_quicktime (f, img, kQTFileTypeTIFF);
+#endif
}
#endif /* MAC_OS */
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
+ {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
struct frame *f;
struct image *img;
{
+#if USE_MAC_IMAGE_IO
+ return image_load_image_io (f, img, kUTTypeGIF);
+#else /* !USE_MAC_IMAGE_IO */
Lisp_Object specified_file, file;
Lisp_Object specified_data;
OSErr err;
time_scale = GetMediaTimeScale (media);
specified_bg = image_spec_value (img->spec, QCbackground, NULL);
- if (!STRINGP (specified_bg) ||
- !mac_defined_color (f, SDATA (specified_bg), &color, 0))
+ if (!STRINGP (specified_bg)
+ || !mac_defined_color (f, SDATA (specified_bg), &color, 0))
{
color.pixel = FRAME_BACKGROUND_PIXEL (f);
color.red = RED16_FROM_ULONG (color.pixel);
if (dh)
DisposeHandle (dh);
return 0;
+#endif /* !USE_MAC_IMAGE_IO */
}
#endif /* MAC_OS */
void
init_image ()
{
-#if defined (MAC_OSX) && TARGET_API_MAC_CARBON
- init_image_func_pointer ();
-#endif
}
/* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
EXFUN (Fset_buffer_multibyte, 1);
EXFUN (Foverlay_start, 1);
EXFUN (Foverlay_end, 1);
+EXFUN (Foverlay_buffer, 1);
extern void adjust_overlays_for_insert P_ ((EMACS_INT, EMACS_INT));
extern void adjust_overlays_for_delete P_ ((EMACS_INT, EMACS_INT));
extern void fix_start_end_in_overlays P_ ((int, int));
#define NO_ARG_ARRAY
-/* Say this machine is a sparc */
+/* Say this machine is a sparc. Probably already defined. */
-#ifndef sparc
-#define sparc
+#ifndef __sparc__
+#define __sparc__
#endif
/* Use type int rather than a union, to represent Lisp_Object */
#ifdef __arch64__ /* GCC, 64-bit ABI. */
#define BITS_PER_LONG 64
+#ifdef __linux__
+#undef START_FILES
+#define START_FILES pre-crt0.o /usr/lib64/crt1.o /usr/lib64/crti.o
+
+/* The duplicate -lgcc is intentional in the definition of LIB_STANDARD.
+ The reason is that some functions in libgcc.a call functions from libc.a,
+ and some libc.a functions need functions from libgcc.a. Since most
+ versions of ld are one-pass linkers, we need to mention -lgcc twice,
+ or else we risk getting unresolved externals. */
+#undef LIB_STANDARD
+#define LIB_STANDARD -lgcc -lc -lgcc /usr/lib64/crtn.o
+#endif
#ifndef _LP64
#define _LP64 /* Done on Alpha -- not sure if it
should be here. -- fx */
#endif
/* The system script code. */
-static int mac_system_script_code;
+static EMACS_INT mac_system_script_code;
/* The system locale identifier string. */
static Lisp_Object Vmac_system_locale;
/* The single script context used for all script executions. */
static OSAID as_script_context;
+#ifndef MAC_OSX
#if TARGET_API_MAC_CARBON
static int wakeup_from_rne_enabled_p = 0;
#define ENABLE_WAKEUP_FROM_RNE (wakeup_from_rne_enabled_p = 1)
#define ENABLE_WAKEUP_FROM_RNE 0
#define DISABLE_WAKEUP_FROM_RNE 0
#endif
+#endif
#ifndef MAC_OSX
static OSErr posix_pathname_to_fsspec P_ ((const char *, FSSpec *));
}
#if TARGET_API_MAC_CARBON
-static OSErr
+OSErr
create_apple_event (class, id, result)
AEEventClass class;
AEEventID id;
return err;
}
-OSStatus
-create_apple_event_from_event_ref (event, num_params, names, types, result)
+Lisp_Object
+mac_event_parameters_to_lisp (event, num_params, names, types)
EventRef event;
UInt32 num_params;
const EventParamName *names;
const EventParamType *types;
- AppleEvent *result;
{
OSStatus err;
- UInt32 i, size;
+ Lisp_Object result = Qnil;
+ UInt32 i;
+ ByteCount size;
+#ifdef MAC_OSX
CFStringRef string;
CFDataRef data;
- char *buf = NULL;
-
- err = create_apple_event (0, 0, result); /* Dummy class and ID. */
- if (err != noErr)
- return err;
-
- for (i = 0; i < num_params; i++)
- switch (types[i])
- {
-#ifdef MAC_OSX
- case typeCFStringRef:
- err = GetEventParameter (event, names[i], typeCFStringRef, NULL,
- sizeof (CFStringRef), NULL, &string);
- if (err != noErr)
- break;
- data = CFStringCreateExternalRepresentation (NULL, string,
- kCFStringEncodingUTF8,
- '?');
- if (data == NULL)
- break;
- AEPutParamPtr (result, names[i], typeUTF8Text,
- CFDataGetBytePtr (data), CFDataGetLength (data));
- CFRelease (data);
- break;
#endif
-
- default:
- err = GetEventParameter (event, names[i], types[i], NULL,
- 0, &size, NULL);
- if (err != noErr)
- break;
- buf = xrealloc (buf, size);
- err = GetEventParameter (event, names[i], types[i], NULL,
- size, NULL, buf);
- if (err == noErr)
- AEPutParamPtr (result, names[i], types[i], buf, size);
- break;
- }
- if (buf)
- xfree (buf);
-
- return noErr;
-}
-
-OSErr
-create_apple_event_from_drag_ref (drag, num_types, types, result)
- DragRef drag;
- UInt32 num_types;
- const FlavorType *types;
- AppleEvent *result;
-{
- OSErr err;
- UInt16 num_items;
- AppleEvent items;
- long index;
char *buf = NULL;
- err = CountDragItems (drag, &num_items);
- if (err != noErr)
- return err;
- err = AECreateList (NULL, 0, false, &items);
- if (err != noErr)
- return err;
-
- for (index = 1; index <= num_items; index++)
+ for (i = 0; i < num_params; i++)
{
- ItemReference item;
- DescType desc_type = typeNull;
- Size size;
+ EventParamName name = names[i];
+ EventParamType type = types[i];
- err = GetDragItemReferenceNumber (drag, index, &item);
- if (err == noErr)
+ switch (type)
{
- int i;
+#ifdef MAC_OSX
+ case typeCFStringRef:
+ err = GetEventParameter (event, name, typeCFStringRef, NULL,
+ sizeof (CFStringRef), NULL, &string);
+ if (err != noErr)
+ break;
+ data = CFStringCreateExternalRepresentation (NULL, string,
+ kCFStringEncodingUTF8,
+ '?');
+ if (data == NULL)
+ break;
+ name = EndianU32_NtoB (name);
+ type = EndianU32_NtoB (typeUTF8Text);
+ result =
+ Fcons (Fcons (make_unibyte_string ((char *) &name, 4),
+ Fcons (make_unibyte_string ((char *) &type, 4),
+ make_unibyte_string (CFDataGetBytePtr (data),
+ CFDataGetLength (data)))),
+ result);
+ CFRelease (data);
+ break;
+#endif
- for (i = 0; i < num_types; i++)
+ default:
+ err = GetEventParameter (event, name, type, NULL, 0, &size, NULL);
+ if (err != noErr)
+ break;
+ buf = xrealloc (buf, size);
+ err = GetEventParameter (event, name, type, NULL, size, NULL, buf);
+ if (err == noErr)
{
- err = GetFlavorDataSize (drag, item, types[i], &size);
- if (err == noErr)
- {
- buf = xrealloc (buf, size);
- err = GetFlavorData (drag, item, types[i], buf, &size, 0);
- }
- if (err == noErr)
- {
- desc_type = types[i];
- break;
- }
+ name = EndianU32_NtoB (name);
+ type = EndianU32_NtoB (type);
+ result =
+ Fcons (Fcons (make_unibyte_string ((char *) &name, 4),
+ Fcons (make_unibyte_string ((char *) &type, 4),
+ make_unibyte_string (buf, size))),
+ result);
}
+ break;
}
- err = AEPutPtr (&items, index, desc_type,
- desc_type != typeNull ? buf : NULL,
- desc_type != typeNull ? size : 0);
- if (err != noErr)
- break;
}
if (buf)
xfree (buf);
- if (err == noErr)
- {
- err = create_apple_event (0, 0, result); /* Dummy class and ID. */
- if (err == noErr)
- err = AEPutParamDesc (result, keyDirectObject, &items);
- if (err != noErr)
- AEDisposeDesc (result);
- }
-
- AEDisposeDesc (&items);
-
- return err;
+ return result;
}
#endif /* TARGET_API_MAC_CARBON */
\f
cfdate_to_lisp (date)
CFDateRef date;
{
- static const CFGregorianDate epoch_gdate = {1970, 1, 1, 0, 0, 0.0};
- static CFAbsoluteTime epoch = 0.0, sec;
- int high, low;
-
- if (epoch == 0.0)
- epoch = CFGregorianDateGetAbsoluteTime (epoch_gdate, NULL);
+ CFTimeInterval sec;
+ int high, low, microsec;
- sec = CFDateGetAbsoluteTime (date) - epoch;
+ sec = CFDateGetAbsoluteTime (date) + kCFAbsoluteTimeIntervalSince1970;
high = sec / 65536.0;
low = sec - high * 65536.0;
+ microsec = (sec - floor (sec)) * 1000000.0;
- return list3 (make_number (high), make_number (low), make_number (0));
+ return list3 (make_number (high), make_number (low), make_number (microsec));
}
GCPRO3 (database, quarks, value);
- BLOCK_INPUT;
-
app_id = kCFPreferencesCurrentApplication;
if (application)
{
CFRelease (key_set);
CFRelease (app_id);
- UNBLOCK_INPUT;
-
UNGCPRO;
return database;
SELECT_TIMEOUT_THRESHOLD_RUNLOOP seconds).
-> Create CFSocket for each socket and add it into the current
event RunLoop so that the current event loop gets quit when
- the socket becomes ready. Then ReceiveNextEvent can wait for
- both kinds of inputs.
+ the socket becomes ready. Then mac_run_loop_run_once can
+ wait for both kinds of inputs.
4. Otherwise.
-> Periodically poll the window input channel while repeatedly
executing `select' with a short timeout
const void *data;
void *info;
{
- int fd = CFSocketGetNative (s);
- SELECT_TYPE *ofds = (SELECT_TYPE *)info;
-
- if ((type == kCFSocketReadCallBack && FD_ISSET (fd, &ofds[0]))
- || (type == kCFSocketConnectCallBack && FD_ISSET (fd, &ofds[1])))
- QuitEventLoop (GetCurrentEventLoop ());
}
#endif /* SELECT_USE_CFSOCKET */
SELECT_TYPE *rfds, *wfds, *efds;
EMACS_TIME *timeout;
{
- OSStatus err = noErr;
+ int timedout_p = 0;
int r = 0;
+ EMACS_TIME select_timeout;
+ EventTimeout timeoutval =
+ (timeout
+ ? (EMACS_SECS (*timeout) * kEventDurationSecond
+ + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
+ : kEventDurationForever);
+ SELECT_TYPE orfds, owfds, oefds;
- /* Try detect_input_pending before ReceiveNextEvent in the same
+ if (timeout == NULL)
+ {
+ if (rfds) orfds = *rfds;
+ if (wfds) owfds = *wfds;
+ if (efds) oefds = *efds;
+ }
+
+ /* Try detect_input_pending before mac_run_loop_run_once in the same
BLOCK_INPUT block, in case that some input has already been read
asynchronously. */
BLOCK_INPUT;
- ENABLE_WAKEUP_FROM_RNE;
- if (!detect_input_pending ())
+ while (1)
{
- EMACS_TIME select_timeout;
- EventTimeout timeoutval =
- (timeout
- ? (EMACS_SECS (*timeout) * kEventDurationSecond
- + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
- : kEventDurationForever);
+ if (detect_input_pending ())
+ break;
EMACS_SET_SECS_USECS (select_timeout, 0, 0);
r = select (nfds, rfds, wfds, efds, &select_timeout);
+ if (r != 0)
+ break;
+
if (timeoutval == 0.0)
- err = eventLoopTimedOutErr;
- else if (r == 0)
+ timedout_p = 1;
+ else
+ timedout_p = mac_run_loop_run_once (timeoutval);
+
+ if (timeout == NULL && timedout_p)
{
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (NULL);
-#endif
- err = ReceiveNextEvent (0, NULL, timeoutval,
- kEventLeaveInQueue, NULL);
+ if (rfds) *rfds = orfds;
+ if (wfds) *wfds = owfds;
+ if (efds) *efds = oefds;
}
+ else
+ break;
}
- DISABLE_WAKEUP_FROM_RNE;
UNBLOCK_INPUT;
if (r != 0)
return r;
- else if (err == noErr)
+ else if (!timedout_p)
{
/* Pretend that `select' is interrupted by a signal. */
detect_input_pending ();
#if SELECT_USE_CFSOCKET
if (getpid () == mac_emacs_pid && cfsockets_for_select)
{
- void *key = (void *) fd;
+ void *key = (void *) (long) fd;
CFSocketRef socket =
(CFSocketRef) CFDictionaryGetValue (cfsockets_for_select, key);
SELECT_TYPE *rfds, *wfds, *efds;
EMACS_TIME *timeout;
{
- OSStatus err = noErr;
+ int timedout_p = 0;
int r;
EMACS_TIME select_timeout;
- static SELECT_TYPE ofds[3];
+ SELECT_TYPE orfds, owfds, oefds;
if (inhibit_window_system || noninteractive
|| nfds < 1 || rfds == NULL || !FD_ISSET (0, rfds))
return select (nfds, rfds, wfds, efds, timeout);
FD_CLR (0, rfds);
- ofds[0] = *rfds;
+ orfds = *rfds;
if (wfds)
- ofds[1] = *wfds;
+ owfds = *wfds;
else
- FD_ZERO (&ofds[1]);
+ FD_ZERO (&owfds);
if (efds)
- ofds[2] = *efds;
+ oefds = *efds;
else
{
EventTimeout timeoutval =
if (r != 0 || timeoutval == 0.0)
return r;
- *rfds = ofds[0];
+ *rfds = orfds;
if (wfds)
- *wfds = ofds[1];
+ *wfds = owfds;
#if SELECT_USE_CFSOCKET
if (timeoutval > 0 && timeoutval <= SELECT_TIMEOUT_THRESHOLD_RUNLOOP)
goto poll_periodically;
- /* Try detect_input_pending before ReceiveNextEvent in the same
- BLOCK_INPUT block, in case that some input has already been
- read asynchronously. */
+ /* Try detect_input_pending before mac_run_loop_run_once in the
+ same BLOCK_INPUT block, in case that some input has already
+ been read asynchronously. */
BLOCK_INPUT;
- ENABLE_WAKEUP_FROM_RNE;
if (!detect_input_pending ())
{
int minfd, fd;
CFRunLoopRef runloop =
(CFRunLoopRef) GetCFRunLoopFromEventLoop (GetCurrentEventLoop ());
- static const CFSocketContext context = {0, ofds, NULL, NULL, NULL};
static CFMutableDictionaryRef sources;
if (sources == NULL)
for (fd = minfd; fd < nfds; fd++)
if (FD_ISSET (fd, rfds) || (wfds && FD_ISSET (fd, wfds)))
{
- void *key = (void *) fd;
+ void *key = (void *) (long) fd;
CFRunLoopSourceRef source =
(CFRunLoopSourceRef) CFDictionaryGetValue (sources, key);
CFSocketCreateWithNative (NULL, fd,
(kCFSocketReadCallBack
| kCFSocketConnectCallBack),
- socket_callback, &context);
+ socket_callback, NULL);
if (socket == NULL)
continue;
CFRunLoopAddSource (runloop, source, kCFRunLoopDefaultMode);
}
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (NULL);
-#endif
- err = ReceiveNextEvent (0, NULL, timeoutval,
- kEventLeaveInQueue, NULL);
+ timedout_p = mac_run_loop_run_once (timeoutval);
for (fd = minfd; fd < nfds; fd++)
if (FD_ISSET (fd, rfds) || (wfds && FD_ISSET (fd, wfds)))
{
- void *key = (void *) fd;
+ void *key = (void *) (long) fd;
CFRunLoopSourceRef source =
(CFRunLoopSourceRef) CFDictionaryGetValue (sources, key);
CFRunLoopRemoveSource (runloop, source, kCFRunLoopDefaultMode);
}
}
- DISABLE_WAKEUP_FROM_RNE;
UNBLOCK_INPUT;
- if (err == noErr || err == eventLoopQuitErr)
+ if (!timedout_p)
{
EMACS_SET_SECS_USECS (select_timeout, 0, 0);
return select_and_poll_event (nfds, rfds, wfds, efds,
if (r != 0)
return r;
- *rfds = ofds[0];
+ *rfds = orfds;
if (wfds)
- *wfds = ofds[1];
+ *wfds = owfds;
if (efds)
- *efds = ofds[2];
+ *efds = oefds;
if (timeout)
{
void
mac_wakeup_from_rne ()
{
+#ifndef MAC_OSX
if (wakeup_from_rne_enabled_p)
/* Post a harmless event so as to wake up from
ReceiveNextEvent. */
mac_post_mouse_moved_event ();
+#endif
}
#endif
void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
-
-extern void mac_get_window_bounds P_ ((struct frame *, Rect *, Rect *));
-
\f
/* Store the screen positions of frame F into XPTR and YPTR.
BLOCK_INPUT;
XSetBackground (dpy, mac->normal_gc, bg);
XSetForeground (dpy, mac->reverse_gc, bg);
- XSetWindowBackground (dpy, FRAME_MAC_WINDOW (f), bg);
+ mac_set_frame_window_background (f, bg);
XSetForeground (dpy, mac->cursor_gc, bg);
UNBLOCK_INPUT;
/* Make sure we redisplay all windows in this frame. */
++windows_or_buffers_changed;
+#if USE_MAC_TOOLBAR
+ FRAME_TOOL_BAR_LINES (f) = 0;
+ if (nlines)
+ {
+ FRAME_EXTERNAL_TOOL_BAR (f) = 1;
+ if (FRAME_MAC_P (f)
+ && !mac_is_window_toolbar_visible (FRAME_MAC_WINDOW (f)))
+ /* Make sure next redisplay shows the tool bar. */
+ XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
+ }
+ else
+ {
+ if (FRAME_EXTERNAL_TOOL_BAR (f))
+ free_frame_tool_bar (f);
+ FRAME_EXTERNAL_TOOL_BAR (f) = 0;
+ }
+
+ return;
+#endif
+
delta = nlines - FRAME_TOOL_BAR_LINES (f);
/* Don't resize the tool-bar to more than we have room for. */
CFStringRef windowTitle =
cfstring_create_with_utf8_cstring (SDATA (name));
- SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle);
+ mac_set_window_title (FRAME_MAC_WINDOW (f), windowTitle);
CFRelease (windowTitle);
#else
Str255 windowTitle;
#endif
}
-#if TARGET_API_MAC_CARBON
-static void
-mac_update_proxy_icon (f)
- struct frame *f;
-{
- OSStatus err;
- Lisp_Object file_name =
- XBUFFER (XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer)->filename;
- Window w = FRAME_MAC_WINDOW (f);
- AliasHandle alias = NULL;
-
- BLOCK_INPUT;
-
- err = GetWindowProxyAlias (w, &alias);
- if (err == errWindowDoesNotHaveProxy && !STRINGP (file_name))
- goto out;
-
- if (STRINGP (file_name))
- {
- AEDesc desc;
-#ifdef MAC_OSX
- FSRef fref, fref_proxy;
-#else
- FSSpec fss, fss_proxy;
-#endif
- Boolean changed;
- Lisp_Object encoded_file_name = ENCODE_FILE (file_name);
-
-#ifdef MAC_OSX
- err = AECoercePtr (TYPE_FILE_NAME, SDATA (encoded_file_name),
- SBYTES (encoded_file_name), typeFSRef, &desc);
-#else
- SetPortWindowPort (w);
- err = AECoercePtr (TYPE_FILE_NAME, SDATA (encoded_file_name),
- SBYTES (encoded_file_name), typeFSS, &desc);
-#endif
- if (err == noErr)
- {
-#ifdef MAC_OSX
- err = AEGetDescData (&desc, &fref, sizeof (FSRef));
-#else
- err = AEGetDescData (&desc, &fss, sizeof (FSSpec));
-#endif
- AEDisposeDesc (&desc);
- }
- if (err == noErr)
- {
- if (alias)
- {
- /* (FS)ResolveAlias never sets `changed' to true if
- `alias' is minimal. */
-#ifdef MAC_OSX
- err = FSResolveAlias (NULL, alias, &fref_proxy, &changed);
- if (err == noErr)
- err = FSCompareFSRefs (&fref, &fref_proxy);
-#else
- err = ResolveAlias (NULL, alias, &fss_proxy, &changed);
- if (err == noErr)
- err = !(fss.vRefNum == fss_proxy.vRefNum
- && fss.parID == fss_proxy.parID
- && EqualString (fss.name, fss_proxy.name,
- false, true));
-#endif
- }
- if (err != noErr || alias == NULL)
- {
- if (alias)
- DisposeHandle ((Handle) alias);
-#ifdef MAC_OSX
- err = FSNewAliasMinimal (&fref, &alias);
-#else
- err = NewAliasMinimal (&fss, &alias);
-#endif
- changed = true;
- }
- }
- if (err == noErr)
- if (changed)
- err = SetWindowProxyAlias (w, alias);
- }
-
- if (alias)
- DisposeHandle ((Handle) alias);
-
- if (err != noErr || !STRINGP (file_name))
- RemoveWindowProxy (w);
-
- out:
- UNBLOCK_INPUT;
-}
-#endif
-
void
mac_update_title_bar (f, save_match_data)
struct frame *f;
|| (!MINI_WINDOW_P (w)
&& (modified_p != !NILP (w->last_had_star))))
{
- SetWindowModified (FRAME_MAC_WINDOW (f),
- !MINI_WINDOW_P (w) && modified_p);
+ BLOCK_INPUT;
+ mac_set_window_modified (FRAME_MAC_WINDOW (f),
+ !MINI_WINDOW_P (w) && modified_p);
mac_update_proxy_icon (f);
+ UNBLOCK_INPUT;
}
#endif
}
mac_window (f)
struct frame *f;
{
- Rect r;
-
BLOCK_INPUT;
- SetRect (&r, f->left_pos, f->top_pos,
- f->left_pos + FRAME_PIXEL_WIDTH (f),
- f->top_pos + FRAME_PIXEL_HEIGHT (f));
-#if TARGET_API_MAC_CARBON
- CreateNewWindow (kDocumentWindowClass,
- kWindowStandardDocumentAttributes
-#ifdef MAC_OSX
- | kWindowToolbarButtonAttribute
-#endif
- , &r, &FRAME_MAC_WINDOW (f));
- if (FRAME_MAC_WINDOW (f))
- {
- SetWRefCon (FRAME_MAC_WINDOW (f), (long) f->output_data.mac);
- if (install_window_handler (FRAME_MAC_WINDOW (f)) != noErr)
- {
- DisposeWindow (FRAME_MAC_WINDOW (f));
- FRAME_MAC_WINDOW (f) = NULL;
- }
- }
-#else
- FRAME_MAC_WINDOW (f)
- = NewCWindow (NULL, &r, "\p", false, zoomDocProc,
- (WindowPtr) -1, 1, (long) f->output_data.mac);
-#endif
- /* so that update events can find this mac_output struct */
- f->output_data.mac->mFP = f; /* point back to emacs frame */
+ mac_create_frame_window (f, 0);
-#ifndef MAC_OSX
if (FRAME_MAC_WINDOW (f))
- {
- ControlRef root_control;
-
- if (CreateRootControl (FRAME_MAC_WINDOW (f), &root_control) != noErr)
- {
- DisposeWindow (FRAME_MAC_WINDOW (f));
- FRAME_MAC_WINDOW (f) = NULL;
- }
- }
+ mac_set_frame_window_background (f, FRAME_BACKGROUND_PIXEL (f));
+
+#if USE_MAC_TOOLBAR
+ /* At the moment, the size of the tool bar is not yet known. We
+ record the gravity value of the newly created window and use it
+ to adjust the position of the window (especially for a negative
+ specification of its vertical position) when the tool bar is
+ first redisplayed. */
+ if (FRAME_EXTERNAL_TOOL_BAR (f))
+ f->output_data.mac->toolbar_win_gravity = f->win_gravity;
#endif
- if (FRAME_MAC_WINDOW (f))
- XSetWindowBackground (FRAME_MAC_DISPLAY(f), FRAME_MAC_WINDOW (f),
- FRAME_BACKGROUND_PIXEL (f));
validate_x_resource_name ();
if (!front_p)
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- if (FrontNonFloatingWindow () == FRAME_MAC_WINDOW (f))
+ if (mac_front_non_floating_window () == FRAME_MAC_WINDOW (f))
SetFrontProcessWithOptions (¤t_psn,
kSetFrontProcessFrontWindowOnly);
else
}
#ifdef MAC_OSX
- ActivateWindow (ActiveNonFloatingWindow (), false);
- ActivateWindow (FRAME_MAC_WINDOW (f), true);
+ mac_activate_window (mac_active_non_floating_window (), false);
+ mac_activate_window (FRAME_MAC_WINDOW (f), true);
#else
#if !TARGET_API_MAC_CARBON
/* SelectWindow (Non-Carbon) does not issue deactivate events if the
{
if (response >= 0x00001040)
{
- err = Gestalt (gestaltSystemVersionMajor, &major);
+ err = Gestalt ('sys1', &major);
if (err == noErr)
- err = Gestalt (gestaltSystemVersionMinor, &minor);
+ err = Gestalt ('sys2', &minor);
if (err == noErr)
- err = Gestalt (gestaltSystemVersionBugFix, &bugfix);
+ err = Gestalt ('sys3', &bugfix);
}
else
{
UNBLOCK_INPUT;
}
#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- else
+ else /* CGDisplayScreenSize == NULL */
#endif
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
UNBLOCK_INPUT;
}
#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- else
+ else /* CGDisplayScreenSize == NULL */
#endif
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
if (FRAME_LIVE_P (f) && FRAME_MAC_P (f)
&& FRAME_MAC_WINDOW (f) != tip_window)
- {
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- if (!f->output_data.mac->hourglass_control)
- {
- Window w = FRAME_MAC_WINDOW (f);
- Rect r;
- ControlRef c;
-
- GetWindowPortBounds (w, &r);
- r.left = r.right - HOURGLASS_WIDTH;
- r.bottom = r.top + HOURGLASS_HEIGHT;
- if (CreateChasingArrowsControl (w, &r, &c) == noErr)
- f->output_data.mac->hourglass_control = c;
- }
-
- if (f->output_data.mac->hourglass_control)
- ShowControl (f->output_data.mac->hourglass_control);
- }
+ mac_show_hourglass (f);
}
hourglass_shown_p = 1;
{
struct frame *f = XFRAME (frame);
- if (FRAME_MAC_P (f)
- /* Watch out for newly created frames. */
- && f->output_data.mac->hourglass_control)
- {
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- HideControl (f->output_data.mac->hourglass_control);
- }
+ if (FRAME_MAC_P (f))
+ mac_hide_hourglass (f);
}
hourglass_shown_p = 0;
window_prompting = x_figure_window_size (f, parms, 0);
- {
- Rect r;
+ BLOCK_INPUT;
- BLOCK_INPUT;
- SetRect (&r, 0, 0, 1, 1);
-#if TARGET_API_MAC_CARBON
- if (CreateNewWindow (kHelpWindowClass,
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- kWindowIgnoreClicksAttribute |
-#endif
- kWindowNoUpdatesAttribute |
- kWindowNoActivatesAttribute,
- &r, &tip_window) == noErr)
-#else
- if (tip_window = NewCWindow (NULL, &r, "\p", false, plainDBox,
- NULL, false, 0L))
-#endif
- {
- FRAME_MAC_WINDOW (f) = tip_window;
- XSetWindowBackground (FRAME_MAC_DISPLAY(f), tip_window,
- FRAME_BACKGROUND_PIXEL (f));
- SetWRefCon (tip_window, (long) f->output_data.mac);
- /* so that update events can find this mac_output struct */
- f->output_data.mac->mFP = f;
- }
- UNBLOCK_INPUT;
- }
+ mac_create_frame_window (f, 1);
+
+ if (FRAME_MAC_WINDOW (f))
+ {
+ mac_set_frame_window_background (f, FRAME_BACKGROUND_PIXEL (f));
+ tip_window = FRAME_MAC_WINDOW (f);
+ }
+
+ UNBLOCK_INPUT;
x_make_gc (f);
Point mouse_pos;
BLOCK_INPUT;
+#if TARGET_API_MAC_CARBON
+ mac_get_global_mouse (&mouse_pos);
+#else
GetMouse (&mouse_pos);
LocalToGlobal (&mouse_pos);
+#endif
*root_x = mouse_pos.h;
*root_y = mouse_pos.v;
UNBLOCK_INPUT;
BLOCK_INPUT;
compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
- MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false);
+ mac_move_window (FRAME_MAC_WINDOW (f), root_x, root_y, false);
UNBLOCK_INPUT;
goto start_timer;
}
compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
BLOCK_INPUT;
- MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false);
- SizeWindow (FRAME_MAC_WINDOW (f), width, height, true);
- ShowWindow (FRAME_MAC_WINDOW (f));
- BringToFront (FRAME_MAC_WINDOW (f));
+ mac_move_window (FRAME_MAC_WINDOW (f), root_x, root_y, false);
+ mac_size_window (FRAME_MAC_WINDOW (f), width, height, true);
+ mac_show_window (FRAME_MAC_WINDOW (f));
+ mac_bring_window_to_front (FRAME_MAC_WINDOW (f));
UNBLOCK_INPUT;
FRAME_PIXEL_WIDTH (f) = width;
\f
-#if TARGET_API_MAC_CARBON
/***********************************************************************
File selection dialog
***********************************************************************/
-static pascal void mac_nav_event_callback P_ ((NavEventCallbackMessage,
- NavCBRecPtr, void *));
-
-/**
- There is a relatively standard way to do this using applescript to run
- a (choose file) method. However, this doesn't do "the right thing"
- by working only if the find-file occurred during a menu or toolbar
- click. So we must do the file dialog by hand, using the navigation
- manager. This also has more flexibility in determining the default
- directory and whether or not we are going to choose a file.
- **/
-
-extern Lisp_Object Qfile_name_history;
-
+#if TARGET_API_MAC_CARBON
DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
doc: /* Read file name, prompting with PROMPT in directory DIR.
Use a file selection dialog.
(prompt, dir, default_filename, mustmatch, only_dir_p)
Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
{
- Lisp_Object file = Qnil;
- int count = SPECPDL_INDEX ();
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
- char filename[MAXPATHLEN];
- static NavEventUPP mac_nav_event_callbackUPP = NULL;
-
- check_mac ();
-
- GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p);
- CHECK_STRING (prompt);
- CHECK_STRING (dir);
-
- /* Create the dialog with PROMPT as title, using DIR as initial
- directory and using "*" as pattern. */
- dir = Fexpand_file_name (dir, Qnil);
-
- {
- OSStatus status;
- NavDialogCreationOptions options;
- NavDialogRef dialogRef;
- NavTypeListHandle fileTypes = NULL;
- NavUserAction userAction;
- CFStringRef message=NULL, saveName = NULL;
-
- BLOCK_INPUT;
- /* No need for a callback function because we are modal */
- NavGetDefaultDialogCreationOptions(&options);
- options.modality = kWindowModalityAppModal;
- options.location.h = options.location.v = -1;
- options.optionFlags = kNavDefaultNavDlogOptions;
- options.optionFlags |= kNavAllFilesInPopup; /* All files allowed */
- options.optionFlags |= kNavSelectAllReadableItem;
- options.optionFlags &= ~kNavAllowMultipleFiles;
- if (!NILP(prompt))
- {
- message = cfstring_create_with_string (prompt);
- options.message = message;
- }
- /* Don't set the application, let it use default.
- options.clientName = CFSTR ("Emacs");
- */
-
- if (mac_nav_event_callbackUPP == NULL)
- mac_nav_event_callbackUPP = NewNavEventUPP (mac_nav_event_callback);
-
- if (!NILP (only_dir_p))
- status = NavCreateChooseFolderDialog(&options, mac_nav_event_callbackUPP,
- NULL, NULL, &dialogRef);
- else if (NILP (mustmatch))
- {
- /* This is a save dialog */
- options.optionFlags |= kNavDontConfirmReplacement;
- options.actionButtonLabel = CFSTR ("Ok");
- options.windowTitle = CFSTR ("Enter name");
-
- if (STRINGP (default_filename))
- {
- Lisp_Object utf8 = ENCODE_UTF_8 (default_filename);
- char *begPtr = SDATA(utf8);
- char *filePtr = begPtr + SBYTES(utf8);
- while (filePtr != begPtr && !IS_DIRECTORY_SEP(filePtr[-1]))
- filePtr--;
- saveName = cfstring_create_with_utf8_cstring (filePtr);
- options.saveFileName = saveName;
- options.optionFlags |= kNavSelectDefaultLocation;
- }
- status = NavCreatePutFileDialog(&options,
- 'TEXT', kNavGenericSignature,
- mac_nav_event_callbackUPP, NULL,
- &dialogRef);
- }
- else
- {
- /* This is an open dialog*/
- status = NavCreateChooseFileDialog(&options, fileTypes,
- mac_nav_event_callbackUPP, NULL,
- NULL, NULL, &dialogRef);
- }
-
- /* Set the default location and continue*/
- if (status == noErr)
- {
- Lisp_Object encoded_dir = ENCODE_FILE (dir);
- AEDesc defLocAed;
-
- status = AECreateDesc (TYPE_FILE_NAME, SDATA (encoded_dir),
- SBYTES (encoded_dir), &defLocAed);
- if (status == noErr)
- {
- NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed);
- AEDisposeDesc(&defLocAed);
- }
- status = NavDialogRun(dialogRef);
- }
-
- if (saveName) CFRelease(saveName);
- if (message) CFRelease(message);
-
- if (status == noErr) {
- userAction = NavDialogGetUserAction(dialogRef);
- switch (userAction)
- {
- case kNavUserActionNone:
- case kNavUserActionCancel:
- break; /* Treat cancel like C-g */
- case kNavUserActionOpen:
- case kNavUserActionChoose:
- case kNavUserActionSaveAs:
- {
- NavReplyRecord reply;
- Size len;
-
- status = NavDialogGetReply(dialogRef, &reply);
- if (status != noErr)
- break;
- status = AEGetNthPtr (&reply.selection, 1, TYPE_FILE_NAME,
- NULL, NULL, filename,
- sizeof (filename) - 1, &len);
- if (status == noErr)
- {
- len = min (len, sizeof (filename) - 1);
- filename[len] = '\0';
- if (reply.saveFileName)
- {
- /* If it was a saved file, we need to add the file name */
- if (len && len < sizeof (filename) - 1
- && filename[len-1] != '/')
- filename[len++] = '/';
- CFStringGetCString(reply.saveFileName, filename+len,
- sizeof (filename) - len,
-#ifdef MAC_OSX
- kCFStringEncodingUTF8
-#else
- CFStringGetSystemEncoding ()
-#endif
- );
- }
- file = DECODE_FILE (make_unibyte_string (filename,
- strlen (filename)));
- }
- NavDisposeReply(&reply);
- }
- break;
- }
- NavDialogDispose(dialogRef);
- UNBLOCK_INPUT;
- }
- else {
- UNBLOCK_INPUT;
- /* Fall back on minibuffer if there was a problem */
- file = Fcompleting_read (prompt, intern ("read-file-name-internal"),
- dir, mustmatch, dir, Qfile_name_history,
- default_filename, Qnil);
- }
- }
-
- UNGCPRO;
-
- /* Make "Cancel" equivalent to C-g. */
- if (NILP (file))
- Fsignal (Qquit, Qnil);
-
- return unbind_to (count, file);
-}
-
-
-/* Need to register some event callback function for enabling drag and
- drop in Navigation Service dialogs. */
-static pascal void
-mac_nav_event_callback (selector, parms, data)
- NavEventCallbackMessage selector;
- NavCBRecPtr parms;
- void *data ;
-{
+ return mac_file_dialog (prompt, dir, default_filename, mustmatch, only_dir_p);
}
#endif
+
\f
/***********************************************************************
Fonts
#undef Z
#define Z (current_buffer->text->z)
#else /* not HAVE_CARBON */
-#include <QuickDraw.h> /* for WindowPtr */
+#include <Quickdraw.h> /* for WindowRef */
#include <QDOffscreen.h> /* for GWorldPtr */
#include <Appearance.h> /* for ThemeCursor */
#include <Windows.h>
/* Whether to use Quartz 2D routines for drawing operations other than
texts. */
#ifndef USE_CG_DRAWING
-#if USE_ATSUI && MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
#define USE_CG_DRAWING 1
#endif
#endif
#endif
#endif
-typedef WindowPtr Window;
+/* Whether to use HIToolbar. */
+#ifndef USE_MAC_TOOLBAR
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 && MAC_OS_X_VERSION_MIN_REQUIRED != 1020
+#define USE_MAC_TOOLBAR 1
+#endif
+#endif
+
+#ifndef CGFLOAT_DEFINED
+typedef float CGFloat;
+#endif
+
+typedef WindowRef Window;
+#if TARGET_API_MAC_CARBON
+typedef ScrapRef Selection;
+#else
+typedef int Selection;
+#endif
+#define mac_set_window_title SetWindowTitleWithCFString
+#define mac_set_window_modified SetWindowModified
+#define mac_is_window_visible IsWindowVisible
+#define mac_is_window_collapsed IsWindowCollapsed
+#define mac_bring_window_to_front BringToFront
+#define mac_send_window_behind SendBehind
+#define mac_hide_window HideWindow
+#define mac_show_window ShowWindow
+#define mac_collapse_window CollapseWindow
+#define mac_front_non_floating_window FrontNonFloatingWindow
+#define mac_active_non_floating_window ActiveNonFloatingWindow
+#define mac_activate_window ActivateWindow
+#define mac_move_window_structure MoveWindowStructure
+#define mac_move_window MoveWindow
+#define mac_size_window SizeWindow
+#define mac_get_global_mouse GetGlobalMouse
+#define mac_is_window_toolbar_visible IsWindowToolbarVisible
+#define mac_rect_make(f, x, y, w, h) CGRectMake (x, y, w, h)
+
+#if USE_MAC_IMAGE_IO
+typedef struct _XImage
+{
+ int width, height; /* size of image */
+ char *data; /* pointer to image data */
+ int bytes_per_line; /* accelarator to next line */
+ int bits_per_pixel; /* bits per pixel (ZPixmap) */
+} *Pixmap;
+#else
typedef GWorldPtr Pixmap;
+#endif
#define Cursor ThemeCursor
#define No_Cursor (-1)
(nr).right = ((nr).left + (width)), \
(nr).bottom = ((nr).top + (height)))
+/* Definitions copied from lwlib.h */
+
+typedef void * XtPointer;
+
+enum button_type
+{
+ BUTTON_TYPE_NONE,
+ BUTTON_TYPE_TOGGLE,
+ BUTTON_TYPE_RADIO
+};
+
+/* This structure is based on the one in ../lwlib/lwlib.h, modified
+ for Mac OS. */
+typedef struct _widget_value
+{
+ /* name of widget */
+ Lisp_Object lname;
+ char* name;
+ /* value (meaning depend on widget type) */
+ char* value;
+ /* keyboard equivalent. no implications for XtTranslations */
+ Lisp_Object lkey;
+ char* key;
+ /* Help string or nil if none.
+ GC finds this string through the frame's menu_bar_vector
+ or through menu_items. */
+ Lisp_Object help;
+ /* true if enabled */
+ Boolean enabled;
+ /* true if selected */
+ Boolean selected;
+ /* The type of a button. */
+ enum button_type button_type;
+ /* true if menu title */
+ Boolean title;
+#if 0
+ /* true if was edited (maintained by get_value) */
+ Boolean edited;
+ /* true if has changed (maintained by lw library) */
+ change_type change;
+ /* true if this widget itself has changed,
+ but not counting the other widgets found in the `next' field. */
+ change_type this_one_change;
+#endif
+ /* Contents of the sub-widgets, also selected slot for checkbox */
+ struct _widget_value* contents;
+ /* data passed to callback */
+ XtPointer call_data;
+ /* next one in the list */
+ struct _widget_value* next;
+#if 0
+ /* slot for the toolkit dependent part. Always initialize to NULL. */
+ void* toolkit_data;
+ /* tell us if we should free the toolkit data slot when freeing the
+ widget_value itself. */
+ Boolean free_toolkit_data;
+
+ /* we resource the widget_value structures; this points to the next
+ one on the free list if this one has been deallocated.
+ */
+ struct _widget_value *free_list;
+#endif
+} widget_value;
+
+#if MAC_OS8
+#define M_APPLE 234
+#define I_ABOUT 1
+
+#define EXTRA_STACK_ALLOC (256 * 1024)
+
+#define ARGV_STRING_LIST_ID 129
+#define RAM_TOO_LARGE_ALERT_ID 129
+#define ABOUT_ALERT_ID 128
+#endif
+
+#define DIALOG_LEFT_MARGIN (112)
+#define DIALOG_TOP_MARGIN (24)
+#define DIALOG_RIGHT_MARGIN (24)
+#define DIALOG_BOTTOM_MARGIN (20)
+#define DIALOG_MIN_INNER_WIDTH (338)
+#define DIALOG_MAX_INNER_WIDTH (564)
+#define DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE (12)
+#define DIALOG_BUTTON_BUTTON_VERTICAL_SPACE (12)
+#define DIALOG_BUTTON_MIN_WIDTH (68)
+#define DIALOG_TEXT_MIN_HEIGHT (50)
+#define DIALOG_TEXT_BUTTONS_VERTICAL_SPACE (10)
+#define DIALOG_ICON_WIDTH (64)
+#define DIALOG_ICON_HEIGHT (64)
+#define DIALOG_ICON_LEFT_MARGIN (24)
+#define DIALOG_ICON_TOP_MARGIN (15)
+
#endif /* EMACS_MACGUI_H */
/* arch-tag: 5a0da49a-35e2-418b-a58c-8a55778ae849
#include "charset.h"
#include "coding.h"
-#if !TARGET_API_MAC_CARBON
-#include <MacTypes.h>
-#include <Menus.h>
-#include <QuickDraw.h>
-#include <ToolUtils.h>
-#include <Fonts.h>
-#include <Controls.h>
-#include <Windows.h>
-#include <Events.h>
-#if defined (__MRC__) || (__MSL__ >= 0x6000)
-#include <ControlDefinitions.h>
-#endif
-#endif /* not TARGET_API_MAC_CARBON */
-
/* This may include sys/types.h, and that somehow loses
if this is not done before the other system files. */
#include "macterm.h"
#include "dispextern.h"
-enum mac_menu_kind { /* Menu ID range */
- MAC_MENU_APPLE, /* 0 (Reserved by Apple) */
- MAC_MENU_MENU_BAR, /* 1 .. 233 */
- MAC_MENU_M_APPLE, /* 234 (== M_APPLE) */
- MAC_MENU_POPUP, /* 235 */
- MAC_MENU_DRIVER, /* 236 .. 255 (Reserved) */
- MAC_MENU_MENU_BAR_SUB, /* 256 .. 16383 */
- MAC_MENU_POPUP_SUB, /* 16384 .. 32767 */
- MAC_MENU_END /* 32768 */
-};
-
-static const int min_menu_id[] = {0, 1, 234, 235, 236, 256, 16384, 32768};
-
-#define DIALOG_WINDOW_RESOURCE 130
-
#if TARGET_API_MAC_CARBON
#define HAVE_DIALOGS 1
#endif
#undef HAVE_MULTILINGUAL_MENU
/******************************************************************/
-/* Definitions copied from lwlib.h */
-
-typedef void * XtPointer;
-
-enum button_type
-{
- BUTTON_TYPE_NONE,
- BUTTON_TYPE_TOGGLE,
- BUTTON_TYPE_RADIO
-};
-
-/* This structure is based on the one in ../lwlib/lwlib.h, modified
- for Mac OS. */
-typedef struct _widget_value
-{
- /* name of widget */
- Lisp_Object lname;
- char* name;
- /* value (meaning depend on widget type) */
- char* value;
- /* keyboard equivalent. no implications for XtTranslations */
- Lisp_Object lkey;
- char* key;
- /* Help string or nil if none.
- GC finds this string through the frame's menu_bar_vector
- or through menu_items. */
- Lisp_Object help;
- /* true if enabled */
- Boolean enabled;
- /* true if selected */
- Boolean selected;
- /* The type of a button. */
- enum button_type button_type;
- /* true if menu title */
- Boolean title;
-#if 0
- /* true if was edited (maintained by get_value) */
- Boolean edited;
- /* true if has changed (maintained by lw library) */
- change_type change;
- /* true if this widget itself has changed,
- but not counting the other widgets found in the `next' field. */
- change_type this_one_change;
-#endif
- /* Contents of the sub-widgets, also selected slot for checkbox */
- struct _widget_value* contents;
- /* data passed to callback */
- XtPointer call_data;
- /* next one in the list */
- struct _widget_value* next;
-#if 0
- /* slot for the toolkit dependent part. Always initialize to NULL. */
- void* toolkit_data;
- /* tell us if we should free the toolkit data slot when freeing the
- widget_value itself. */
- Boolean free_toolkit_data;
-
- /* we resource the widget_value structures; this points to the next
- one on the free list if this one has been deallocated.
- */
- struct _widget_value *free_list;
-#endif
-} widget_value;
/* Assumed by other routines to zero area returned. */
#define malloc_widget_value() (void *)memset (xmalloc (sizeof (widget_value)),\
static void list_of_panes P_ ((Lisp_Object));
static void list_of_items P_ ((Lisp_Object));
-static void find_and_call_menu_selection P_ ((FRAME_PTR, int, Lisp_Object,
- void *));
-static int fill_menu P_ ((MenuHandle, widget_value *, enum mac_menu_kind, int));
-static void fill_menubar P_ ((widget_value *, int));
-static void dispose_menus P_ ((enum mac_menu_kind, int));
-
\f
/* This holds a Lisp vector that holds the results of decoding
the keymaps or alist-of-alists that specify a menu.
static int menu_items_submenu_depth;
/* Nonzero means a menu is currently active. */
-static int popup_activated_flag;
+int popup_activated_flag;
/* This is set nonzero after the user activates the menu bar, and set
to zero again after the menu bars are redisplayed by prepare_menu_bar.
#ifdef HAVE_MENUS
-/* Regard ESC and C-g as Cancel even without the Cancel button. */
-
-#ifdef MAC_OSX
-static Boolean
-mac_dialog_modal_filter (dialog, event, item_hit)
- DialogRef dialog;
- EventRecord *event;
- DialogItemIndex *item_hit;
-{
- Boolean result;
-
- result = StdFilterProc (dialog, event, item_hit);
- if (result == false
- && (event->what == keyDown || event->what == autoKey)
- && ((event->message & charCodeMask) == kEscapeCharCode
- || mac_quit_char_key_p (event->modifiers,
- (event->message & keyCodeMask) >> 8)))
- {
- *item_hit = kStdCancelItemIndex;
- return true;
- }
-
- return result;
-}
-#endif
-
DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0,
doc: /* Pop up a dialog box and return user's selection.
POSITION specifies which frame to use.
but I don't want to make one now. */
CHECK_WINDOW (window);
-#ifdef MAC_OSX
- /* Special treatment for Fmessage_box, Fyes_or_no_p, and Fy_or_n_p. */
- if (EQ (position, Qt)
- && STRINGP (Fcar (contents))
- && ((!NILP (Fequal (XCDR (contents),
- Fcons (Fcons (build_string ("OK"), Qt), Qnil)))
- && EQ (header, Qt))
- || (!NILP (Fequal (XCDR (contents),
- Fcons (Fcons (build_string ("Yes"), Qt),
- Fcons (Fcons (build_string ("No"), Qnil),
- Qnil))))
- && NILP (header))))
- {
- OSStatus err = noErr;
- AlertStdCFStringAlertParamRec param;
- CFStringRef error_string, explanation_string;
- DialogRef alert;
- DialogItemIndex item_hit;
- Lisp_Object tem;
-
- /* Force a redisplay before showing the dialog. If a frame is
- created just before showing the dialog, its contents may not
- have been fully drawn. */
- Fredisplay (Qt);
-
- tem = Fstring_match (concat3 (build_string ("\\("),
- call0 (intern ("sentence-end")),
- build_string ("\\)\n")),
- XCAR (contents), Qnil);
- BLOCK_INPUT;
- if (NILP (tem))
- {
- error_string = cfstring_create_with_string (XCAR (contents));
- if (error_string == NULL)
- err = memFullErr;
- explanation_string = NULL;
- }
- else
- {
- tem = Fmatch_end (make_number (1));
- error_string =
- cfstring_create_with_string (Fsubstring (XCAR (contents),
- make_number (0), tem));
- if (error_string == NULL)
- err = memFullErr;
- else
- {
- XSETINT (tem, XINT (tem) + 1);
- explanation_string =
- cfstring_create_with_string (Fsubstring (XCAR (contents),
- tem, Qnil));
- if (explanation_string == NULL)
- {
- CFRelease (error_string);
- err = memFullErr;
- }
- }
- }
- if (err == noErr)
- err = GetStandardAlertDefaultParams (¶m,
- kStdCFStringAlertVersionOne);
- if (err == noErr)
- {
- param.movable = true;
- param.position = kWindowAlertPositionParentWindow;
- if (NILP (header))
- {
- param.defaultText = CFSTR ("Yes");
- param.otherText = CFSTR ("No");
-#if 0
- param.cancelText = CFSTR ("Cancel");
- param.cancelButton = kAlertStdAlertCancelButton;
-#endif
- }
- err = CreateStandardAlert (kAlertNoteAlert, error_string,
- explanation_string, ¶m, &alert);
- CFRelease (error_string);
- if (explanation_string)
- CFRelease (explanation_string);
- }
- if (err == noErr)
- err = RunStandardAlert (alert, mac_dialog_modal_filter, &item_hit);
- UNBLOCK_INPUT;
-
- if (err == noErr)
- {
- if (item_hit == kStdCancelItemIndex)
- Fsignal (Qquit, Qnil);
- else if (item_hit == kStdOkItemIndex)
- return Qt;
- else
- return Qnil;
- }
- }
-#endif
#ifndef HAVE_DIALOGS
/* Display a menu with these alternatives
in the middle of frame F. */
#endif /* HAVE_DIALOGS */
}
-/* Activate the menu bar of frame F.
- This is called from keyboard.c when it gets the
- MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue.
-
- To activate the menu bar, we use the button-press event location
- that was saved in saved_menu_event_location.
-
- But first we recompute the menu bar contents (the whole tree).
-
- The reason for saving the button event until here, instead of
- passing it to the toolkit right away, is that we can safely
- execute Lisp code. */
-
-void
-x_activate_menubar (f)
- FRAME_PTR f;
-{
- SInt32 menu_choice;
- SInt16 menu_id, menu_item;
- extern Point saved_menu_event_location;
-
- set_frame_menubar (f, 0, 1);
- BLOCK_INPUT;
-
- popup_activated_flag = 1;
- menu_choice = MenuSelect (saved_menu_event_location);
- popup_activated_flag = 0;
- menu_id = HiWord (menu_choice);
- menu_item = LoWord (menu_choice);
-
-#if !TARGET_API_MAC_CARBON
- if (menu_id == min_menu_id[MAC_MENU_M_APPLE])
- do_apple_menu (menu_item);
- else
-#endif
- if (menu_id)
- {
- MenuHandle menu = GetMenuHandle (menu_id);
-
- if (menu)
- {
- UInt32 refcon;
-
- GetMenuItemRefCon (menu, menu_item, &refcon);
- find_and_call_menu_selection (f, f->menu_bar_items_used,
- f->menu_bar_vector, (void *) refcon);
- }
- }
-
- HiliteMenu (0);
-
- UNBLOCK_INPUT;
-}
-
/* Find the menu selection and store it in the keyboard buffer.
F is the frame the menu is on.
MENU_BAR_ITEMS_USED is the length of VECTOR.
VECTOR is an array of menu events for the whole menu. */
-static void
+void
find_and_call_menu_selection (f, menu_bar_items_used, vector, client_data)
FRAME_PTR f;
int menu_bar_items_used;
}
\f
-#if TARGET_API_MAC_CARBON
-extern Lisp_Object Vshow_help_function;
-
-static Lisp_Object
-restore_show_help_function (old_show_help_function)
- Lisp_Object old_show_help_function;
-{
- Vshow_help_function = old_show_help_function;
-
- return Qnil;
-}
-
-static pascal OSStatus
-menu_target_item_handler (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err, result;
- MenuRef menu;
- MenuItemIndex menu_item;
- Lisp_Object help;
- GrafPtr port;
- int specpdl_count = SPECPDL_INDEX ();
-
- result = CallNextEventHandler (next_handler, event);
-
- err = GetEventParameter (event, kEventParamDirectObject, typeMenuRef,
- NULL, sizeof (MenuRef), NULL, &menu);
- if (err == noErr)
- err = GetEventParameter (event, kEventParamMenuItemIndex,
- typeMenuItemIndex, NULL,
- sizeof (MenuItemIndex), NULL, &menu_item);
- if (err == noErr)
- err = GetMenuItemProperty (menu, menu_item,
- MAC_EMACS_CREATOR_CODE, 'help',
- sizeof (Lisp_Object), NULL, &help);
- if (err != noErr)
- help = Qnil;
-
- /* Temporarily bind Vshow_help_function to Qnil because we don't
- want tooltips during menu tracking. */
- record_unwind_protect (restore_show_help_function, Vshow_help_function);
- Vshow_help_function = Qnil;
- GetPort (&port);
- show_help_echo (help, Qnil, Qnil, Qnil, 1);
- SetPort (port);
- unbind_to (specpdl_count, Qnil);
-
- return err == noErr ? noErr : result;
-}
-#endif
-
-OSStatus
-install_menu_target_item_handler (window)
- WindowPtr window;
-{
- OSStatus err = noErr;
-#if TARGET_API_MAC_CARBON
- static const EventTypeSpec specs[] =
- {{kEventClassMenu, kEventMenuTargetItem}};
- static EventHandlerUPP menu_target_item_handlerUPP = NULL;
-
- if (menu_target_item_handlerUPP == NULL)
- menu_target_item_handlerUPP =
- NewEventHandlerUPP (menu_target_item_handler);
-
- err = InstallWindowEventHandler (window, menu_target_item_handlerUPP,
- GetEventTypeCount (specs), specs,
- NULL, NULL);
-#endif
- return err;
-}
-
-/* Event handler function that pops down a menu on C-g. We can only pop
- down menus if CancelMenuTracking is present (OSX 10.3 or later). */
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
-static pascal OSStatus
-menu_quit_handler (nextHandler, theEvent, userData)
- EventHandlerCallRef nextHandler;
- EventRef theEvent;
- void* userData;
-{
- OSStatus err;
- UInt32 keyCode;
- UInt32 keyModifiers;
-
- err = GetEventParameter (theEvent, kEventParamKeyCode,
- typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
-
- if (err == noErr)
- err = GetEventParameter (theEvent, kEventParamKeyModifiers,
- typeUInt32, NULL, sizeof(UInt32),
- NULL, &keyModifiers);
-
- if (err == noErr && mac_quit_char_key_p (keyModifiers, keyCode))
- {
- MenuRef menu = userData != 0
- ? (MenuRef)userData : AcquireRootMenu ();
-
- CancelMenuTracking (menu, true, 0);
- if (!userData) ReleaseMenu (menu);
- return noErr;
- }
-
- return CallNextEventHandler (nextHandler, theEvent);
-}
-#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
-
-/* Add event handler to all menus that belong to KIND so we can detect C-g.
- MENU_HANDLE is the root menu of the tracking session to dismiss
- when C-g is detected. NULL means the menu bar.
- If CancelMenuTracking isn't available, do nothing. */
-
-static void
-install_menu_quit_handler (kind, menu_handle)
- enum mac_menu_kind kind;
- MenuHandle menu_handle;
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
- static const EventTypeSpec typesList[] =
- {{kEventClassKeyboard, kEventRawKeyDown}};
- int id;
-
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- if (CancelMenuTracking == NULL)
- return;
-#endif
- for (id = min_menu_id[kind]; id < min_menu_id[kind + 1]; id++)
- {
- MenuHandle menu = GetMenuHandle (id);
-
- if (menu == NULL)
- break;
- InstallMenuEventHandler (menu, menu_quit_handler,
- GetEventTypeCount (typesList),
- typesList, menu_handle, NULL);
- }
-#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
-}
-
/* Set the contents of the menubar widgets of frame F.
The argument FIRST_TIME is currently ignored;
it is set the first time this is called, from initialize_frame_menubar. */
XSETFRAME (Vmenu_updating_frame, f);
+ /* This seems to be unnecessary for Carbon. */
+#if 0
if (! menubar_widget)
deep_p = 1;
else if (pending_menu_activation && !deep_p)
deep_p = 1;
+#endif
if (deep_p)
{
/* Non-null value to indicate menubar has already been "created". */
f->output_data.mac->menubar_widget = 1;
- fill_menubar (first_wv->contents, deep_p);
+ mac_fill_menubar (first_wv->contents, deep_p);
- /* Add event handler so we can detect C-g. */
- install_menu_quit_handler (MAC_MENU_MENU_BAR, NULL);
- install_menu_quit_handler (MAC_MENU_MENU_BAR_SUB, NULL);
free_menubar_widget_value_tree (first_wv);
UNBLOCK_INPUT;
}
\f
-static Lisp_Object
-pop_down_menu (arg)
- Lisp_Object arg;
-{
- struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
- FRAME_PTR f = p->pointer;
- MenuHandle menu = GetMenuHandle (min_menu_id[MAC_MENU_POPUP]);
-
- BLOCK_INPUT;
-
- /* Must reset this manually because the button release event is not
- passed to Emacs event loop. */
- FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0;
-
- /* delete all menus */
- dispose_menus (MAC_MENU_POPUP_SUB, 0);
- DeleteMenu (min_menu_id[MAC_MENU_POPUP]);
- DisposeMenu (menu);
-
- UNBLOCK_INPUT;
-
- return Qnil;
-}
+/* The item selected in the popup menu. */
+int menu_item_selection;
/* Mac_menu_show actually displays a menu using the panes and items in
menu_items and returns the value selected from it; we assume input
char **error;
{
int i;
- int menu_item_choice;
- UInt32 menu_item_selection;
- MenuHandle menu;
- Point pos;
widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
widget_value **submenu_stack
= (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
int submenu_depth = 0;
int first_pane;
- int specpdl_count = SPECPDL_INDEX ();
*error = NULL;
first_wv->contents = wv_title;
}
- /* Actually create the menu. */
- menu = NewMenu (min_menu_id[MAC_MENU_POPUP], "\p");
- InsertMenu (menu, -1);
- fill_menu (menu, first_wv->contents, MAC_MENU_POPUP_SUB,
- min_menu_id[MAC_MENU_POPUP_SUB]);
-
- /* Free the widget_value objects we used to specify the
- contents. */
- free_menubar_widget_value_tree (first_wv);
-
- /* Adjust coordinates to be root-window-relative. */
- pos.h = x;
- pos.v = y;
-
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
- LocalToGlobal (&pos);
-
/* No selection has been chosen yet. */
menu_item_selection = 0;
- record_unwind_protect (pop_down_menu, make_save_value (f, 0));
-
- /* Add event handler so we can detect C-g. */
- install_menu_quit_handler (MAC_MENU_POPUP, menu);
- install_menu_quit_handler (MAC_MENU_POPUP_SUB, menu);
-
- /* Display the menu. */
- popup_activated_flag = 1;
- menu_item_choice = PopUpMenuSelect (menu, pos.v, pos.h, 0);
- popup_activated_flag = 0;
+ /* Actually create and show the menu until popped down. */
+ create_and_show_popup_menu (f, first_wv, x, y, for_click);
- /* Get the refcon to find the correct item */
- if (menu_item_choice)
- {
- MenuHandle sel_menu = GetMenuHandle (HiWord (menu_item_choice));
-
- if (sel_menu)
- GetMenuItemRefCon (sel_menu, LoWord (menu_item_choice),
- &menu_item_selection);
- }
-
- unbind_to (specpdl_count, Qnil);
+ /* Free the widget_value objects we used to specify the contents. */
+ free_menubar_widget_value_tree (first_wv);
/* Find the selected item, and its pane, to return
the proper value. */
#ifdef HAVE_DIALOGS
/* Construct native Mac OS dialog based on widget_value tree. */
-#if TARGET_API_MAC_CARBON
-
-static pascal OSStatus
-mac_handle_dialog_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus err;
- WindowRef window = (WindowRef) data;
-
- switch (GetEventClass (event))
- {
- case kEventClassCommand:
- {
- HICommand command;
-
- err = GetEventParameter (event, kEventParamDirectObject,
- typeHICommand, NULL, sizeof (HICommand),
- NULL, &command);
- if (err == noErr)
- if ((command.commandID & ~0xffff) == 'Bt\0\0')
- {
- SetWRefCon (window, command.commandID);
- err = QuitAppModalLoopForWindow (window);
-
- return err == noErr ? noErr : eventNotHandledErr;
- }
-
- return CallNextEventHandler (next_handler, event);
- }
- break;
-
- case kEventClassKeyboard:
- {
- OSStatus result;
- char char_code;
-
- result = CallNextEventHandler (next_handler, event);
- if (result == noErr)
- return noErr;
-
- err = GetEventParameter (event, kEventParamKeyMacCharCodes,
- typeChar, NULL, sizeof (char),
- NULL, &char_code);
- if (err == noErr)
- switch (char_code)
- {
- case kEscapeCharCode:
- err = QuitAppModalLoopForWindow (window);
- break;
-
- default:
- {
- UInt32 modifiers, key_code;
-
- err = GetEventParameter (event, kEventParamKeyModifiers,
- typeUInt32, NULL, sizeof (UInt32),
- NULL, &modifiers);
- if (err == noErr)
- err = GetEventParameter (event, kEventParamKeyCode,
- typeUInt32, NULL, sizeof (UInt32),
- NULL, &key_code);
- if (err == noErr)
- {
- if (mac_quit_char_key_p (modifiers, key_code))
- err = QuitAppModalLoopForWindow (window);
- else
- err = eventNotHandledErr;
- }
- }
- break;
- }
-
- return err == noErr ? noErr : result;
- }
- break;
-
- default:
- abort ();
- }
-}
-
-static OSStatus
-install_dialog_event_handler (window)
- WindowRef window;
-{
- static const EventTypeSpec specs[] =
- {{kEventClassCommand, kEventCommandProcess},
- {kEventClassKeyboard, kEventRawKeyDown}};
- static EventHandlerUPP handle_dialog_eventUPP = NULL;
-
- if (handle_dialog_eventUPP == NULL)
- handle_dialog_eventUPP = NewEventHandlerUPP (mac_handle_dialog_event);
- return InstallWindowEventHandler (window, handle_dialog_eventUPP,
- GetEventTypeCount (specs), specs,
- window, NULL);
-}
-
-#define DIALOG_LEFT_MARGIN (112)
-#define DIALOG_TOP_MARGIN (24)
-#define DIALOG_RIGHT_MARGIN (24)
-#define DIALOG_BOTTOM_MARGIN (20)
-#define DIALOG_MIN_INNER_WIDTH (338)
-#define DIALOG_MAX_INNER_WIDTH (564)
-#define DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE (12)
-#define DIALOG_BUTTON_BUTTON_VERTICAL_SPACE (12)
-#define DIALOG_BUTTON_MIN_WIDTH (68)
-#define DIALOG_TEXT_MIN_HEIGHT (50)
-#define DIALOG_TEXT_BUTTONS_VERTICAL_SPACE (10)
-#define DIALOG_ICON_WIDTH (64)
-#define DIALOG_ICON_HEIGHT (64)
-#define DIALOG_ICON_LEFT_MARGIN (24)
-#define DIALOG_ICON_TOP_MARGIN (15)
-
-static int
-create_and_show_dialog (f, first_wv)
- FRAME_PTR f;
- widget_value *first_wv;
-{
- OSStatus err;
- char *dialog_name, *message;
- int nb_buttons, first_group_count, i, result = 0;
- widget_value *wv;
- short buttons_height, text_height, inner_width, inner_height;
- Rect empty_rect, *rects;
- WindowRef window = NULL;
- ControlRef *buttons, default_button = NULL, text;
-
- dialog_name = first_wv->name;
- nb_buttons = dialog_name[1] - '0';
- first_group_count = nb_buttons - (dialog_name[4] - '0');
-
- wv = first_wv->contents;
- message = wv->value;
-
- wv = wv->next;
- SetRect (&empty_rect, 0, 0, 0, 0);
-
- /* Create dialog window. */
- err = CreateNewWindow (kMovableModalWindowClass,
- kWindowStandardHandlerAttribute,
- &empty_rect, &window);
- if (err == noErr)
- err = SetThemeWindowBackground (window, kThemeBrushMovableModalBackground,
- true);
- if (err == noErr)
- err = SetWindowTitleWithCFString (window, (dialog_name[0] == 'Q'
- ? CFSTR ("Question")
- : CFSTR ("Information")));
-
- /* Create button controls and measure their optimal bounds. */
- if (err == noErr)
- {
- buttons = alloca (sizeof (ControlRef) * nb_buttons);
- rects = alloca (sizeof (Rect) * nb_buttons);
- for (i = 0; i < nb_buttons; i++)
- {
- CFStringRef label = cfstring_create_with_utf8_cstring (wv->value);
-
- if (label == NULL)
- err = memFullErr;
- else
- {
- err = CreatePushButtonControl (window, &empty_rect,
- label, &buttons[i]);
- CFRelease (label);
- }
- if (err == noErr)
- {
- if (!wv->enabled)
- {
-#ifdef MAC_OSX
- err = DisableControl (buttons[i]);
-#else
- err = DeactivateControl (buttons[i]);
-#endif
- }
- else if (default_button == NULL)
- default_button = buttons[i];
- }
- if (err == noErr)
- {
- SInt16 unused;
-
- rects[i] = empty_rect;
- err = GetBestControlRect (buttons[i], &rects[i], &unused);
- }
- if (err == noErr)
- {
- OffsetRect (&rects[i], -rects[i].left, -rects[i].top);
- if (rects[i].right < DIALOG_BUTTON_MIN_WIDTH)
- rects[i].right = DIALOG_BUTTON_MIN_WIDTH;
- else if (rects[i].right > DIALOG_MAX_INNER_WIDTH)
- rects[i].right = DIALOG_MAX_INNER_WIDTH;
-
- err = SetControlCommandID (buttons[i],
- 'Bt\0\0' + (int) wv->call_data);
- }
- if (err != noErr)
- break;
- wv = wv->next;
- }
- }
-
- /* Layout buttons. rects[i] is set relative to the bottom-right
- corner of the inner box. */
- if (err == noErr)
- {
- short bottom, right, max_height, left_align_shift;
-
- inner_width = DIALOG_MIN_INNER_WIDTH;
- bottom = right = max_height = 0;
- for (i = 0; i < nb_buttons; i++)
- {
- if (right - rects[i].right < - inner_width)
- {
- if (i != first_group_count
- && right - rects[i].right >= - DIALOG_MAX_INNER_WIDTH)
- inner_width = - (right - rects[i].right);
- else
- {
- bottom -= max_height + DIALOG_BUTTON_BUTTON_VERTICAL_SPACE;
- right = max_height = 0;
- }
- }
- if (max_height < rects[i].bottom)
- max_height = rects[i].bottom;
- OffsetRect (&rects[i], right - rects[i].right,
- bottom - rects[i].bottom);
- right = rects[i].left - DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE;
- if (i == first_group_count - 1)
- right -= DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE;
- }
- buttons_height = - (bottom - max_height);
-
- left_align_shift = - (inner_width + rects[nb_buttons - 1].left);
- for (i = nb_buttons - 1; i >= first_group_count; i--)
- {
- if (bottom != rects[i].bottom)
- {
- left_align_shift = - (inner_width + rects[i].left);
- bottom = rects[i].bottom;
- }
- OffsetRect (&rects[i], left_align_shift, 0);
- }
- }
-
- /* Create a static text control and measure its bounds. */
- if (err == noErr)
- {
- CFStringRef message_string;
- Rect bounds;
-
- message_string = cfstring_create_with_utf8_cstring (message);
- if (message_string == NULL)
- err = memFullErr;
- else
- {
- ControlFontStyleRec text_style;
-
- text_style.flags = 0;
- SetRect (&bounds, 0, 0, inner_width, 0);
- err = CreateStaticTextControl (window, &bounds, message_string,
- &text_style, &text);
- CFRelease (message_string);
- }
- if (err == noErr)
- {
- SInt16 unused;
-
- bounds = empty_rect;
- err = GetBestControlRect (text, &bounds, &unused);
- }
- if (err == noErr)
- {
- text_height = bounds.bottom - bounds.top;
- if (text_height < DIALOG_TEXT_MIN_HEIGHT)
- text_height = DIALOG_TEXT_MIN_HEIGHT;
- }
- }
-
- /* Place buttons. */
- if (err == noErr)
- {
- inner_height = (text_height + DIALOG_TEXT_BUTTONS_VERTICAL_SPACE
- + buttons_height);
-
- for (i = 0; i < nb_buttons; i++)
- {
- OffsetRect (&rects[i], DIALOG_LEFT_MARGIN + inner_width,
- DIALOG_TOP_MARGIN + inner_height);
- SetControlBounds (buttons[i], &rects[i]);
- }
- }
-
- /* Place text. */
- if (err == noErr)
- {
- Rect bounds;
-
- SetRect (&bounds, DIALOG_LEFT_MARGIN, DIALOG_TOP_MARGIN,
- DIALOG_LEFT_MARGIN + inner_width,
- DIALOG_TOP_MARGIN + text_height);
- SetControlBounds (text, &bounds);
- }
-
- /* Create the application icon at the upper-left corner. */
- if (err == noErr)
- {
- ControlButtonContentInfo content;
- ControlRef icon;
- static const ProcessSerialNumber psn = {0, kCurrentProcess};
-#ifdef MAC_OSX
- FSRef app_location;
-#else
- ProcessInfoRec pinfo;
- FSSpec app_spec;
-#endif
- SInt16 unused;
-
- content.contentType = kControlContentIconRef;
-#ifdef MAC_OSX
- err = GetProcessBundleLocation (&psn, &app_location);
- if (err == noErr)
- err = GetIconRefFromFileInfo (&app_location, 0, NULL, 0, NULL,
- kIconServicesNormalUsageFlag,
- &content.u.iconRef, &unused);
-#else
- bzero (&pinfo, sizeof (ProcessInfoRec));
- pinfo.processInfoLength = sizeof (ProcessInfoRec);
- pinfo.processAppSpec = &app_spec;
- err = GetProcessInformation (&psn, &pinfo);
- if (err == noErr)
- err = GetIconRefFromFile (&app_spec, &content.u.iconRef, &unused);
-#endif
- if (err == noErr)
- {
- Rect bounds;
-
- SetRect (&bounds, DIALOG_ICON_LEFT_MARGIN, DIALOG_ICON_TOP_MARGIN,
- DIALOG_ICON_LEFT_MARGIN + DIALOG_ICON_WIDTH,
- DIALOG_ICON_TOP_MARGIN + DIALOG_ICON_HEIGHT);
- err = CreateIconControl (window, &bounds, &content, true, &icon);
- ReleaseIconRef (content.u.iconRef);
- }
- }
-
- /* Show the dialog window and run event loop. */
- if (err == noErr)
- if (default_button)
- err = SetWindowDefaultButton (window, default_button);
- if (err == noErr)
- err = install_dialog_event_handler (window);
- if (err == noErr)
- {
- SizeWindow (window,
- DIALOG_LEFT_MARGIN + inner_width + DIALOG_RIGHT_MARGIN,
- DIALOG_TOP_MARGIN + inner_height + DIALOG_BOTTOM_MARGIN,
- true);
- err = RepositionWindow (window, FRAME_MAC_WINDOW (f),
- kWindowAlertPositionOnParentWindow);
- }
- if (err == noErr)
- {
- SetWRefCon (window, 0);
- ShowWindow (window);
- BringToFront (window);
- err = RunAppModalLoopForWindow (window);
- }
- if (err == noErr)
- {
- UInt32 command_id = GetWRefCon (window);
-
- if ((command_id & ~0xffff) == 'Bt\0\0')
- result = command_id - 'Bt\0\0';
- }
-
- if (window)
- DisposeWindow (window);
-
- return result;
-}
-#else /* not TARGET_API_MAC_CARBON */
-static int
-mac_dialog (widget_value *wv)
-{
- char *dialog_name;
- char *prompt;
- char **button_labels;
- UInt32 *ref_cons;
- int nb_buttons;
- int left_count;
- int i;
- int dialog_width;
- Rect rect;
- WindowPtr window_ptr;
- ControlHandle ch;
- int left;
- EventRecord event_record;
- SInt16 part_code;
- int control_part_code;
- Point mouse;
-
- dialog_name = wv->name;
- nb_buttons = dialog_name[1] - '0';
- left_count = nb_buttons - (dialog_name[4] - '0');
- button_labels = (char **) alloca (sizeof (char *) * nb_buttons);
- ref_cons = (UInt32 *) alloca (sizeof (UInt32) * nb_buttons);
-
- wv = wv->contents;
- prompt = (char *) alloca (strlen (wv->value) + 1);
- strcpy (prompt, wv->value);
- c2pstr (prompt);
-
- wv = wv->next;
- for (i = 0; i < nb_buttons; i++)
- {
- button_labels[i] = wv->value;
- button_labels[i] = (char *) alloca (strlen (wv->value) + 1);
- strcpy (button_labels[i], wv->value);
- c2pstr (button_labels[i]);
- ref_cons[i] = (UInt32) wv->call_data;
- wv = wv->next;
- }
-
- window_ptr = GetNewCWindow (DIALOG_WINDOW_RESOURCE, NULL, (WindowPtr) -1);
-
- SetPortWindowPort (window_ptr);
-
- TextFont (0);
- /* Left and right margins in the dialog are 13 pixels each.*/
- dialog_width = 14;
- /* Calculate width of dialog box: 8 pixels on each side of the text
- label in each button, 12 pixels between buttons. */
- for (i = 0; i < nb_buttons; i++)
- dialog_width += StringWidth (button_labels[i]) + 16 + 12;
-
- if (left_count != 0 && nb_buttons - left_count != 0)
- dialog_width += 12;
-
- dialog_width = max (dialog_width, StringWidth (prompt) + 26);
-
- SizeWindow (window_ptr, dialog_width, 78, 0);
- ShowWindow (window_ptr);
-
- SetPortWindowPort (window_ptr);
-
- TextFont (0);
-
- MoveTo (13, 29);
- DrawString (prompt);
-
- left = 13;
- for (i = 0; i < nb_buttons; i++)
- {
- int button_width = StringWidth (button_labels[i]) + 16;
- SetRect (&rect, left, 45, left + button_width, 65);
- ch = NewControl (window_ptr, &rect, button_labels[i], 1, 0, 0, 0,
- kControlPushButtonProc, ref_cons[i]);
- left += button_width + 12;
- if (i == left_count - 1)
- left += 12;
- }
-
- i = 0;
- while (!i)
- {
- if (WaitNextEvent (mDownMask, &event_record, 10, NULL))
- if (event_record.what == mouseDown)
- {
- part_code = FindWindow (event_record.where, &window_ptr);
- if (part_code == inContent)
- {
- mouse = event_record.where;
- GlobalToLocal (&mouse);
- control_part_code = FindControl (mouse, window_ptr, &ch);
- if (control_part_code == kControlButtonPart)
- if (TrackControl (ch, mouse, NULL))
- i = GetControlReference (ch);
- }
- }
- }
-
- DisposeWindow (window_ptr);
-
- return i;
-}
-#endif /* not TARGET_API_MAC_CARBON */
-
static char * button_names [] = {
"button1", "button2", "button3", "button4", "button5",
"button6", "button7", "button8", "button9", "button10" };
{
int i, nb_buttons=0;
char dialog_name[6];
- int menu_item_selection;
widget_value *wv, *first_wv = 0, *prev_wv = 0;
if (!NILP (descrip))
wv->key = (char *) SDATA (descrip);
wv->value = (char *) SDATA (item_name);
- wv->call_data = (void *) i;
+ wv->call_data = (void *) (EMACS_INT) i;
/* menu item is identified by its index in menu_items table */
wv->enabled = !NILP (enable);
wv->help = Qnil;
first_wv = wv;
}
+ /* No selection has been chosen yet. */
+ menu_item_selection = 0;
+
/* Force a redisplay before showing the dialog. If a frame is created
just before showing the dialog, its contents may not have been fully
drawn. */
/* Actually create the dialog. */
#if TARGET_API_MAC_CARBON
- menu_item_selection = create_and_show_dialog (f, first_wv);
+ create_and_show_dialog (f, first_wv);
#else
menu_item_selection = mac_dialog (first_wv);
#endif
\f
/* Is this item a separator? */
-static int
+int
name_is_separator (name)
const char *name;
{
them like normal separators. */
return (*name == '\0' || start + 2 == name);
}
-
-static void
-add_menu_item (menu, pos, wv)
- MenuHandle menu;
- int pos;
- widget_value *wv;
-{
-#if TARGET_API_MAC_CARBON
- CFStringRef item_name;
-#else
- Str255 item_name;
-#endif
-
- if (name_is_separator (wv->name))
- AppendMenu (menu, "\p-");
- else
- {
- AppendMenu (menu, "\pX");
-
-#if TARGET_API_MAC_CARBON
- item_name = cfstring_create_with_utf8_cstring (wv->name);
-
- if (wv->key != NULL)
- {
- CFStringRef name, key;
-
- name = item_name;
- key = cfstring_create_with_utf8_cstring (wv->key);
- item_name = CFStringCreateWithFormat (NULL, NULL, CFSTR ("%@ %@"),
- name, key);
- CFRelease (name);
- CFRelease (key);
- }
-
- SetMenuItemTextWithCFString (menu, pos, item_name);
- CFRelease (item_name);
-
- if (wv->enabled)
- EnableMenuItem (menu, pos);
- else
- DisableMenuItem (menu, pos);
-
- if (STRINGP (wv->help))
- SetMenuItemProperty (menu, pos, MAC_EMACS_CREATOR_CODE, 'help',
- sizeof (Lisp_Object), &wv->help);
-#else /* ! TARGET_API_MAC_CARBON */
- item_name[sizeof (item_name) - 1] = '\0';
- strncpy (item_name, wv->name, sizeof (item_name) - 1);
- if (wv->key != NULL)
- {
- int len = strlen (item_name);
-
- strncpy (item_name + len, " ", sizeof (item_name) - 1 - len);
- len = strlen (item_name);
- strncpy (item_name + len, wv->key, sizeof (item_name) - 1 - len);
- }
- c2pstr (item_name);
- SetMenuItemText (menu, pos, item_name);
-
- if (wv->enabled)
- EnableItem (menu, pos);
- else
- DisableItem (menu, pos);
-#endif /* ! TARGET_API_MAC_CARBON */
-
- /* Draw radio buttons and tickboxes. */
- if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE ||
- wv->button_type == BUTTON_TYPE_RADIO))
- SetItemMark (menu, pos, checkMark);
- else
- SetItemMark (menu, pos, noMark);
-
- SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data);
- }
-}
-
-/* Construct native Mac OS menu based on widget_value tree. */
-
-static int
-fill_menu (menu, wv, kind, submenu_id)
- MenuHandle menu;
- widget_value *wv;
- enum mac_menu_kind kind;
- int submenu_id;
-{
- int pos;
-
- for (pos = 1; wv != NULL; wv = wv->next, pos++)
- {
- add_menu_item (menu, pos, wv);
- if (wv->contents && submenu_id < min_menu_id[kind + 1])
- {
- MenuHandle submenu = NewMenu (submenu_id, "\pX");
-
- InsertMenu (submenu, -1);
- SetMenuItemHierarchicalID (menu, pos, submenu_id);
- submenu_id = fill_menu (submenu, wv->contents, kind, submenu_id + 1);
- }
- }
-
- return submenu_id;
-}
-
-/* Construct native Mac OS menubar based on widget_value tree. */
-
-static void
-fill_menubar (wv, deep_p)
- widget_value *wv;
- int deep_p;
-{
- int id, submenu_id;
- MenuHandle menu;
- Str255 title;
-#if !TARGET_API_MAC_CARBON
- int title_changed_p = 0;
-#endif
-
- /* Clean up the menu bar when filled by the entire menu trees. */
- if (deep_p)
- {
- dispose_menus (MAC_MENU_MENU_BAR, 0);
- dispose_menus (MAC_MENU_MENU_BAR_SUB, 0);
-#if !TARGET_API_MAC_CARBON
- title_changed_p = 1;
-#endif
- }
-
- /* Fill menu bar titles and submenus. Reuse the existing menu bar
- titles as much as possible to minimize redraw (if !deep_p). */
- submenu_id = min_menu_id[MAC_MENU_MENU_BAR_SUB];
- for (id = min_menu_id[MAC_MENU_MENU_BAR];
- wv != NULL && id < min_menu_id[MAC_MENU_MENU_BAR + 1];
- wv = wv->next, id++)
- {
- strncpy (title, wv->name, 255);
- title[255] = '\0';
- c2pstr (title);
-
- menu = GetMenuHandle (id);
- if (menu)
- {
-#if TARGET_API_MAC_CARBON
- Str255 old_title;
-
- GetMenuTitle (menu, old_title);
- if (!EqualString (title, old_title, false, false))
- {
-#ifdef MAC_OSX
- if (id + 1 == min_menu_id[MAC_MENU_MENU_BAR + 1]
- || GetMenuRef (id + 1) == NULL)
- {
- /* This is a workaround for Mac OS X 10.5 where just
- calling SetMenuTitle fails to change the title of
- the last (Help) menu in the menu bar. */
- DeleteMenu (id);
- DisposeMenu (menu);
- menu = NULL;
- }
- else
-#endif /* MAC_OSX */
- SetMenuTitle (menu, title);
- }
-#else /* !TARGET_API_MAC_CARBON */
- if (!EqualString (title, (*menu)->menuData, false, false))
- {
- DeleteMenu (id);
- DisposeMenu (menu);
- menu = NewMenu (id, title);
- InsertMenu (menu, GetMenuHandle (id + 1) ? id + 1 : 0);
- title_changed_p = 1;
- }
-#endif /* !TARGET_API_MAC_CARBON */
- }
-
- if (!menu)
- {
- menu = NewMenu (id, title);
- InsertMenu (menu, 0);
-#if !TARGET_API_MAC_CARBON
- title_changed_p = 1;
-#endif
- }
-
- if (wv->contents)
- submenu_id = fill_menu (menu, wv->contents, MAC_MENU_MENU_BAR_SUB,
- submenu_id);
- }
-
- if (id < min_menu_id[MAC_MENU_MENU_BAR + 1] && GetMenuHandle (id))
- {
- dispose_menus (MAC_MENU_MENU_BAR, id);
-#if !TARGET_API_MAC_CARBON
- title_changed_p = 1;
-#endif
- }
-
-#if !TARGET_API_MAC_CARBON
- if (title_changed_p)
- InvalMenuBar ();
-#endif
-}
-
-/* Dispose of menus that belong to KIND, and remove them from the menu
- list. ID is the lower bound of menu IDs that will be processed. */
-
-static void
-dispose_menus (kind, id)
- enum mac_menu_kind kind;
- int id;
-{
- for (id = max (id, min_menu_id[kind]); id < min_menu_id[kind + 1]; id++)
- {
- MenuHandle menu = GetMenuHandle (id);
-
- if (menu == NULL)
- break;
- DeleteMenu (id);
- DisposeMenu (menu);
- }
-}
-
#endif /* HAVE_MENUS */
/* Detect if a menu is currently active. */
doc: /* Return t if a menu or popup dialog is active. */)
()
{
+#if TARGET_API_MAC_CARBON
+ return (popup_activated ()) ? Qt : Qnil;
+#else
/* Always return Qnil since menu selection functions do not return
until a selection has been made or cancelled. */
return Qnil;
+#endif
}
\f
void
#if !TARGET_API_MAC_CARBON
#include <Endian.h>
-typedef int ScrapRef;
-typedef ResType ScrapFlavorType;
-#endif /* !TARGET_API_MAC_CARBON */
-
-static OSStatus get_scrap_from_symbol P_ ((Lisp_Object, int, ScrapRef *));
-static ScrapFlavorType get_flavor_type_from_symbol P_ ((Lisp_Object));
-static int valid_scrap_target_type_p P_ ((Lisp_Object));
-static OSStatus clear_scrap P_ ((ScrapRef *));
-static OSStatus put_scrap_string P_ ((ScrapRef, Lisp_Object, Lisp_Object));
-static OSStatus put_scrap_private_timestamp P_ ((ScrapRef, unsigned long));
-static ScrapFlavorType scrap_has_target_type P_ ((ScrapRef, Lisp_Object));
-static Lisp_Object get_scrap_string P_ ((ScrapRef, Lisp_Object));
-static OSStatus get_scrap_private_timestamp P_ ((ScrapRef, unsigned long *));
-static Lisp_Object get_scrap_target_type_list P_ ((ScrapRef));
+#endif
+
static void x_own_selection P_ ((Lisp_Object, Lisp_Object));
static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int));
static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object,
Lisp_Object,
Lisp_Object));
-EXFUN (Fx_selection_owner_p, 1);
-#ifdef MAC_OSX
-static OSStatus mac_handle_service_event P_ ((EventHandlerCallRef,
- EventRef, void *));
-void init_service_handler P_ ((void));
-#endif
Lisp_Object QPRIMARY, QSECONDARY, QTIMESTAMP, QTARGETS;
static Lisp_Object Vx_lost_selection_functions;
-/* Coding system for communicating with other programs via scrap. */
+/* Coding system for communicating with other programs via selections. */
static Lisp_Object Vselection_coding_system;
/* Coding system for the next communicating with other programs. */
extern unsigned long last_event_timestamp;
/* This is an association list whose elements are of the form
- ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME)
+ ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME OWNERSHIP-INFO)
SELECTION-NAME is a lisp symbol.
SELECTION-VALUE is the value that emacs owns for that selection.
It may be any kind of Lisp object.
SELECTION-TIMESTAMP is the time at which emacs began owning this selection,
as a cons of two 16-bit numbers (making a 32 bit time.)
FRAME is the frame for which we made the selection.
- If there is an entry in this alist, and the data for the flavor
- type SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP in the corresponding scrap
- (if exists) coincides with SELECTION-TIMESTAMP, then it can be
- assumed that Emacs owns that selection.
+ OWNERSHIP-INFO is a value saved when emacs owns for that selection.
+ If another application takes the ownership of that selection
+ later, then newly examined ownership info value should be
+ different from the saved one.
+ If there is an entry in this alist, the current ownership info for
+ the selection coincides with OWNERSHIP-INFO, then it can be
+ assumed that Emacs owns that selection.
The only (eq) parts of this list that are visible from Lisp are the
selection-values. */
static Lisp_Object Vselection_alist;
-#define SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP 'Etsp'
-
/* This is an alist whose CARs are selection-types and whose CDRs are
the names of Lisp functions to call to convert the given Emacs
selection value to a string representing the given selection type.
This is for Lisp-level extension of the emacs selection
handling. */
-static Lisp_Object Vselection_converter_alist;
+Lisp_Object Vselection_converter_alist;
/* A selection name (represented as a Lisp symbol) can be associated
with a named scrap via `mac-scrap-name' property. Likewise for a
selection type with a scrap flavor type via `mac-ostype'. */
-static Lisp_Object Qmac_scrap_name, Qmac_ostype;
+Lisp_Object Qmac_scrap_name, Qmac_ostype;
-#ifdef MAC_OSX
-/* Selection name for communication via Services menu. */
-static Lisp_Object Vmac_service_selection;
-#endif
-\f
-/* Get a reference to the scrap corresponding to the symbol SYM. The
- reference is set to *SCRAP, and it becomes NULL if there's no
- corresponding scrap. Clear the scrap if CLEAR_P is non-zero. */
-
-static OSStatus
-get_scrap_from_symbol (sym, clear_p, scrap)
- Lisp_Object sym;
- int clear_p;
- ScrapRef *scrap;
-{
- OSStatus err = noErr;
- Lisp_Object str = Fget (sym, Qmac_scrap_name);
-
- if (!STRINGP (str))
- *scrap = NULL;
- else
- {
-#if TARGET_API_MAC_CARBON
-#ifdef MAC_OSX
- CFStringRef scrap_name = cfstring_create_with_string (str);
- OptionBits options = (clear_p ? kScrapClearNamedScrap
- : kScrapGetNamedScrap);
-
- err = GetScrapByName (scrap_name, options, scrap);
- CFRelease (scrap_name);
-#else /* !MAC_OSX */
- if (clear_p)
- err = ClearCurrentScrap ();
- if (err == noErr)
- err = GetCurrentScrap (scrap);
-#endif /* !MAC_OSX */
-#else /* !TARGET_API_MAC_CARBON */
- if (clear_p)
- err = ZeroScrap ();
- if (err == noErr)
- *scrap = 1;
-#endif /* !TARGET_API_MAC_CARBON */
- }
-
- return err;
-}
-
-/* Get a scrap flavor type from the symbol SYM. Return 0 if no
- corresponding flavor type. */
-
-static ScrapFlavorType
-get_flavor_type_from_symbol (sym)
- Lisp_Object sym;
-{
- Lisp_Object str = Fget (sym, Qmac_ostype);
-
- if (STRINGP (str) && SBYTES (str) == 4)
- return EndianU32_BtoN (*((UInt32 *) SDATA (str)));
-
- return 0;
-}
-
-/* Check if the symbol SYM has a corresponding scrap flavor type. */
-
-static int
-valid_scrap_target_type_p (sym)
- Lisp_Object sym;
-{
- return get_flavor_type_from_symbol (sym) != 0;
-}
-
-/* Clear the scrap whose reference is *SCRAP. */
-
-static INLINE OSStatus
-clear_scrap (scrap)
- ScrapRef *scrap;
-{
-#if TARGET_API_MAC_CARBON
-#ifdef MAC_OSX
- return ClearScrap (scrap);
-#else
- return ClearCurrentScrap ();
-#endif
-#else /* !TARGET_API_MAC_CARBON */
- return ZeroScrap ();
-#endif /* !TARGET_API_MAC_CARBON */
-}
-
-/* Put Lisp String STR to the scrap SCRAP. The target type is
- specified by TYPE. */
-
-static OSStatus
-put_scrap_string (scrap, type, str)
- ScrapRef scrap;
- Lisp_Object type, str;
-{
- ScrapFlavorType flavor_type = get_flavor_type_from_symbol (type);
-
- if (flavor_type == 0)
- return noTypeErr;
-
-#if TARGET_API_MAC_CARBON
- return PutScrapFlavor (scrap, flavor_type, kScrapFlavorMaskNone,
- SBYTES (str), SDATA (str));
-#else /* !TARGET_API_MAC_CARBON */
- return PutScrap (SBYTES (str), flavor_type, SDATA (str));
-#endif /* !TARGET_API_MAC_CARBON */
-}
-
-/* Put TIMESTAMP to the scrap SCRAP. The timestamp is used for
- checking if the scrap is owned by the process. */
-
-static INLINE OSStatus
-put_scrap_private_timestamp (scrap, timestamp)
- ScrapRef scrap;
- unsigned long timestamp;
-{
-#if TARGET_API_MAC_CARBON
- return PutScrapFlavor (scrap, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP,
- kScrapFlavorMaskSenderOnly,
- sizeof (timestamp), ×tamp);
-#else /* !TARGET_API_MAC_CARBON */
- return PutScrap (sizeof (timestamp), SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP,
- ×tamp);
-#endif /* !TARGET_API_MAC_CARBON */
-}
-
-/* Check if data for the target type TYPE is available in SCRAP. */
-
-static ScrapFlavorType
-scrap_has_target_type (scrap, type)
- ScrapRef scrap;
- Lisp_Object type;
-{
- OSStatus err;
- ScrapFlavorType flavor_type = get_flavor_type_from_symbol (type);
-
- if (flavor_type)
- {
-#if TARGET_API_MAC_CARBON
- ScrapFlavorFlags flags;
-
- err = GetScrapFlavorFlags (scrap, flavor_type, &flags);
- if (err != noErr)
- flavor_type = 0;
-#else /* !TARGET_API_MAC_CARBON */
- SInt32 size, offset;
-
- size = GetScrap (NULL, flavor_type, &offset);
- if (size < 0)
- flavor_type = 0;
-#endif /* !TARGET_API_MAC_CARBON */
- }
-
- return flavor_type;
-}
-
-/* Get data for the target type TYPE from SCRAP and create a Lisp
- string. Return nil if failed to get data. */
-
-static Lisp_Object
-get_scrap_string (scrap, type)
- ScrapRef scrap;
- Lisp_Object type;
-{
- OSStatus err;
- Lisp_Object result = Qnil;
- ScrapFlavorType flavor_type = get_flavor_type_from_symbol (type);
-#if TARGET_API_MAC_CARBON
- Size size;
-
- if (flavor_type)
- {
- err = GetScrapFlavorSize (scrap, flavor_type, &size);
- if (err == noErr)
- {
- do
- {
- result = make_uninit_string (size);
- err = GetScrapFlavorData (scrap, flavor_type,
- &size, SDATA (result));
- if (err != noErr)
- result = Qnil;
- else if (size < SBYTES (result))
- result = make_unibyte_string (SDATA (result), size);
- }
- while (STRINGP (result) && size > SBYTES (result));
- }
- }
-#else
- Handle handle;
- SInt32 size, offset;
-
- if (flavor_type)
- size = GetScrap (NULL, flavor_type, &offset);
- if (size >= 0)
- {
- handle = NewHandle (size);
- HLock (handle);
- size = GetScrap (handle, flavor_type, &offset);
- if (size >= 0)
- result = make_unibyte_string (*handle, size);
- DisposeHandle (handle);
- }
-#endif
-
- return result;
-}
-
-/* Get timestamp from the scrap SCRAP and set to *TIMPSTAMP. */
-
-static OSStatus
-get_scrap_private_timestamp (scrap, timestamp)
- ScrapRef scrap;
- unsigned long *timestamp;
-{
- OSStatus err = noErr;
-#if TARGET_API_MAC_CARBON
- ScrapFlavorFlags flags;
-
- err = GetScrapFlavorFlags (scrap, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP, &flags);
- if (err == noErr)
- {
- if (!(flags & kScrapFlavorMaskSenderOnly))
- err = noTypeErr;
- else
- {
- Size size = sizeof (*timestamp);
-
- err = GetScrapFlavorData (scrap, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP,
- &size, timestamp);
- if (err == noErr && size != sizeof (*timestamp))
- err = noTypeErr;
- }
- }
-#else /* !TARGET_API_MAC_CARBON */
- Handle handle;
- SInt32 size, offset;
-
- size = GetScrap (NULL, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP, &offset);
- if (size == sizeof (*timestamp))
- {
- handle = NewHandle (size);
- HLock (handle);
- size = GetScrap (handle, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP, &offset);
- if (size == sizeof (*timestamp))
- *timestamp = *((unsigned long *) *handle);
- DisposeHandle (handle);
- }
- if (size != sizeof (*timestamp))
- err = noTypeErr;
-#endif /* !TARGET_API_MAC_CARBON */
-
- return err;
-}
-
-/* Get the list of target types in SCRAP. The return value is a list
- of target type symbols possibly followed by scrap flavor type
- strings. */
-
-static Lisp_Object
-get_scrap_target_type_list (scrap)
- ScrapRef scrap;
-{
- Lisp_Object result = Qnil, rest, target_type;
-#if TARGET_API_MAC_CARBON
- OSStatus err;
- UInt32 count, i, type;
- ScrapFlavorInfo *flavor_info = NULL;
- Lisp_Object strings = Qnil;
-
- err = GetScrapFlavorCount (scrap, &count);
- if (err == noErr)
- flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count);
- err = GetScrapFlavorInfoList (scrap, &count, flavor_info);
- if (err != noErr)
- {
- xfree (flavor_info);
- flavor_info = NULL;
- }
- if (flavor_info == NULL)
- count = 0;
-#endif
- for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest))
- {
- ScrapFlavorType flavor_type = 0;
-
- if (CONSP (XCAR (rest))
- && (target_type = XCAR (XCAR (rest)),
- SYMBOLP (target_type))
- && (flavor_type = scrap_has_target_type (scrap, target_type)))
- {
- result = Fcons (target_type, result);
-#if TARGET_API_MAC_CARBON
- for (i = 0; i < count; i++)
- if (flavor_info[i].flavorType == flavor_type)
- {
- flavor_info[i].flavorType = 0;
- break;
- }
-#endif
- }
- }
-#if TARGET_API_MAC_CARBON
- if (flavor_info)
- {
- for (i = 0; i < count; i++)
- if (flavor_info[i].flavorType)
- {
- type = EndianU32_NtoB (flavor_info[i].flavorType);
- strings = Fcons (make_unibyte_string ((char *) &type, 4), strings);
- }
- result = nconc2 (result, strings);
- xfree (flavor_info);
- }
-#endif
-
- return result;
-}
\f
/* Do protocol to assert ourself as a selection owner.
Update the Vselection_alist so that we can reply to later requests for
Lisp_Object selection_name, selection_value;
{
OSStatus err;
- ScrapRef scrap;
+ Selection sel;
struct gcpro gcpro1, gcpro2;
- Lisp_Object rest, handler_fn, value, type;
+ Lisp_Object rest, handler_fn, value, target_type;
int count;
CHECK_SYMBOL (selection_name);
BLOCK_INPUT;
- err = get_scrap_from_symbol (selection_name, 1, &scrap);
- if (err == noErr && scrap)
+ err = mac_get_selection_from_symbol (selection_name, 1, &sel);
+ if (err == noErr && sel)
{
/* Don't allow a quit within the converter.
When the user types C-g, he would be surprised
for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest))
{
if (!(CONSP (XCAR (rest))
- && (type = XCAR (XCAR (rest)),
- SYMBOLP (type))
- && valid_scrap_target_type_p (type)
+ && (target_type = XCAR (XCAR (rest)),
+ SYMBOLP (target_type))
+ && mac_valid_selection_target_p (target_type)
&& (handler_fn = XCDR (XCAR (rest)),
SYMBOLP (handler_fn))))
continue;
if (!NILP (handler_fn))
value = call3 (handler_fn, selection_name,
- type, selection_value);
+ target_type, selection_value);
- if (STRINGP (value))
- err = put_scrap_string (scrap, type, value);
+ if (NILP (value))
+ continue;
+
+ if (mac_valid_selection_value_p (value, target_type))
+ err = mac_put_selection_value (sel, target_type, value);
else if (CONSP (value)
- && EQ (XCAR (value), type)
- && STRINGP (XCDR (value)))
- err = put_scrap_string (scrap, type, XCDR (value));
+ && EQ (XCAR (value), target_type)
+ && mac_valid_selection_value_p (XCDR (value), target_type))
+ err = mac_put_selection_value (sel, target_type, XCDR (value));
}
unbind_to (count, Qnil);
-
- if (err == noErr)
- err = put_scrap_private_timestamp (scrap, last_event_timestamp);
}
UNBLOCK_INPUT;
UNGCPRO;
- if (scrap && err != noErr)
+ if (sel && err != noErr)
error ("Can't set selection");
/* Now update the local cache */
{
Lisp_Object selection_time;
Lisp_Object selection_data;
+ Lisp_Object ownership_info;
Lisp_Object prev_value;
selection_time = long_to_cons (last_event_timestamp);
+ if (sel)
+ {
+ BLOCK_INPUT;
+ ownership_info = mac_get_selection_ownership_info (sel);
+ UNBLOCK_INPUT;
+ }
+ else
+ ownership_info = Qnil; /* dummy value for local-only selection */
selection_data = Fcons (selection_name,
Fcons (selection_value,
Fcons (selection_time,
- Fcons (selected_frame, Qnil))));
+ Fcons (selected_frame,
+ Fcons (ownership_info,
+ Qnil)))));
prev_value = assq_no_quit (selection_name, Vselection_alist);
Vselection_alist = Fcons (selection_data, Vselection_alist);
unbind_to (count, Qnil);
}
+ if (local_request)
+ return value;
+
/* Make sure this value is of a type that we could transmit
- to another X client. */
+ to another application. */
+ type = target_type;
check = value;
if (CONSP (value)
&& SYMBOLP (XCAR (value)))
type = XCAR (value),
check = XCDR (value);
- if (STRINGP (check)
- || VECTORP (check)
- || SYMBOLP (check)
- || INTEGERP (check)
- || NILP (value))
- return value;
- /* Check for a value that cons_to_long could handle. */
- else if (CONSP (check)
- && INTEGERP (XCAR (check))
- && (INTEGERP (XCDR (check))
- ||
- (CONSP (XCDR (check))
- && INTEGERP (XCAR (XCDR (check)))
- && NILP (XCDR (XCDR (check))))))
+ if (NILP (value) || mac_valid_selection_value_p (check, type))
return value;
signal_error ("Invalid data returned by selection-conversion function",
Lisp_Object selection_symbol, target_type, time_stamp;
{
OSStatus err;
- ScrapRef scrap;
+ Selection sel;
Lisp_Object result = Qnil;
BLOCK_INPUT;
- err = get_scrap_from_symbol (selection_symbol, 0, &scrap);
- if (err == noErr && scrap)
+ err = mac_get_selection_from_symbol (selection_symbol, 0, &sel);
+ if (err == noErr && sel)
{
if (EQ (target_type, QTARGETS))
{
- result = get_scrap_target_type_list (scrap);
+ result = mac_get_selection_target_list (sel);
result = Fvconcat (1, &result);
}
else
{
- result = get_scrap_string (scrap, target_type);
+ result = mac_get_selection_value (sel, target_type);
if (STRINGP (result))
Fput_text_property (make_number (0), make_number (SBYTES (result)),
Qforeign_selection, target_type, result);
Lisp_Object time;
{
OSStatus err;
- ScrapRef scrap;
+ Selection sel;
Lisp_Object local_selection_data;
check_mac ();
BLOCK_INPUT;
- err = get_scrap_from_symbol (selection, 0, &scrap);
- if (err == noErr && scrap)
- clear_scrap (&scrap);
+ err = mac_get_selection_from_symbol (selection, 0, &sel);
+ if (err == noErr && sel)
+ mac_clear_selection (&sel);
UNBLOCK_INPUT;
Lisp_Object selection;
{
OSStatus err;
- ScrapRef scrap;
+ Selection sel;
Lisp_Object result = Qnil, local_selection_data;
check_mac ();
BLOCK_INPUT;
- err = get_scrap_from_symbol (selection, 0, &scrap);
- if (err == noErr && scrap)
+ err = mac_get_selection_from_symbol (selection, 0, &sel);
+ if (err == noErr && sel)
{
- unsigned long timestamp;
+ Lisp_Object ownership_info;
- err = get_scrap_private_timestamp (scrap, ×tamp);
- if (err == noErr
- && (timestamp
- == cons_to_long (XCAR (XCDR (XCDR (local_selection_data))))))
+ ownership_info = XCAR (XCDR (XCDR (XCDR (XCDR (local_selection_data)))));
+ if (!NILP (Fequal (ownership_info,
+ mac_get_selection_ownership_info (sel))))
result = Qt;
}
else
Lisp_Object selection;
{
OSStatus err;
- ScrapRef scrap;
+ Selection sel;
Lisp_Object result = Qnil, rest;
/* It should be safe to call this before we have an Mac frame. */
BLOCK_INPUT;
- err = get_scrap_from_symbol (selection, 0, &scrap);
- if (err == noErr && scrap)
+ err = mac_get_selection_from_symbol (selection, 0, &sel);
+ if (err == noErr && sel)
for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest))
{
if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))
- && scrap_has_target_type (scrap, XCAR (XCAR (rest))))
+ && mac_selection_has_target_p (sel, XCAR (XCAR (rest))))
{
result = Qt;
break;
Apple event support
***********************************************************************/
int mac_ready_for_apple_events = 0;
-static Lisp_Object Vmac_apple_event_map;
-static Lisp_Object Qmac_apple_event_class, Qmac_apple_event_id;
+Lisp_Object Vmac_apple_event_map;
+Lisp_Object Qmac_apple_event_class, Qmac_apple_event_id;
static Lisp_Object Qemacs_suspension_id;
extern Lisp_Object Qundefined;
extern void mac_store_apple_event P_ ((Lisp_Object, Lisp_Object,
return err;
}
-static pascal OSErr
+pascal OSErr
mac_handle_apple_event (apple_event, reply, refcon)
const AppleEvent *apple_event;
AppleEvent *reply;
return nresumed;
}
-static void
+void
cleanup_all_suspended_apple_events ()
{
cleanup_suspended_apple_events (&deferred_apple_events, 1);
cleanup_suspended_apple_events (&suspended_apple_events, 1);
}
-void
-init_apple_event_handler ()
-{
- OSErr err;
- long result;
-
- /* Make sure we have Apple events before starting. */
- err = Gestalt (gestaltAppleEventsAttr, &result);
- if (err != noErr)
- abort ();
-
- if (!(result & (1 << gestaltAppleEventsPresent)))
- abort ();
-
- err = AEInstallEventHandler (typeWildCard, typeWildCard,
-#if TARGET_API_MAC_CARBON
- NewAEEventHandlerUPP (mac_handle_apple_event),
-#else
- NewAEEventHandlerProc (mac_handle_apple_event),
-#endif
- 0L, false);
- if (err != noErr)
- abort ();
-
- atexit (cleanup_all_suspended_apple_events);
-}
-
static UInt32
get_suspension_id (apple_event)
Lisp_Object apple_event;
}
AESetTheCurrentEvent (&ae->apple_event);
AEResumeTheCurrentEvent (&ae->apple_event, &ae->reply,
- ((AEEventHandlerUPP)
- (EQ (error_code, Qt) ?
- kAEUseStandardDispatch : kAENoDispatch)),
- 0);
+ (EQ (error_code, Qt)
+ ? (AEEventHandlerUPP) kAEUseStandardDispatch
+ : (AEEventHandlerUPP) kAENoDispatch), 0);
AEDisposeDesc (&ae->reply);
AEDisposeDesc (&ae->apple_event);
xfree (ae);
Drag and drop support
***********************************************************************/
#if TARGET_API_MAC_CARBON
-static Lisp_Object Vmac_dnd_known_types;
-static pascal OSErr mac_do_track_drag P_ ((DragTrackingMessage, WindowRef,
- void *, DragRef));
-static pascal OSErr mac_do_receive_drag P_ ((WindowRef, void *, DragRef));
-static DragTrackingHandlerUPP mac_do_track_dragUPP = NULL;
-static DragReceiveHandlerUPP mac_do_receive_dragUPP = NULL;
-
-extern void mac_store_drag_event P_ ((WindowRef, Point, SInt16,
- const AEDesc *));
-
-static pascal OSErr
-mac_do_track_drag (message, window, refcon, drag)
- DragTrackingMessage message;
- WindowRef window;
- void *refcon;
- DragRef drag;
-{
- OSErr err = noErr;
- static int can_accept;
- UInt16 num_items, index;
-
- if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
- return dragNotAcceptedErr;
-
- switch (message)
- {
- case kDragTrackingEnterHandler:
- err = CountDragItems (drag, &num_items);
- if (err != noErr)
- break;
- can_accept = 0;
- for (index = 1; index <= num_items; index++)
- {
- ItemReference item;
- FlavorFlags flags;
- Lisp_Object rest;
-
- err = GetDragItemReferenceNumber (drag, index, &item);
- if (err != noErr)
- continue;
- for (rest = Vmac_dnd_known_types; CONSP (rest); rest = XCDR (rest))
- {
- Lisp_Object str;
- FlavorType type;
-
- str = XCAR (rest);
- if (!(STRINGP (str) && SBYTES (str) == 4))
- continue;
- type = EndianU32_BtoN (*((UInt32 *) SDATA (str)));
-
- err = GetFlavorFlags (drag, item, type, &flags);
- if (err == noErr)
- {
- can_accept = 1;
- break;
- }
- }
- }
- break;
-
- case kDragTrackingEnterWindow:
- if (can_accept)
- {
- RgnHandle hilite_rgn = NewRgn ();
-
- if (hilite_rgn)
- {
- Rect r;
-
- GetWindowPortBounds (window, &r);
- OffsetRect (&r, -r.left, -r.top);
- RectRgn (hilite_rgn, &r);
- ShowDragHilite (drag, hilite_rgn, true);
- DisposeRgn (hilite_rgn);
- }
- SetThemeCursor (kThemeCopyArrowCursor);
- }
- break;
-
- case kDragTrackingInWindow:
- break;
-
- case kDragTrackingLeaveWindow:
- if (can_accept)
- {
- HideDragHilite (drag);
- SetThemeCursor (kThemeArrowCursor);
- }
- break;
-
- case kDragTrackingLeaveHandler:
- break;
- }
-
- if (err != noErr)
- return dragNotAcceptedErr;
- return noErr;
-}
-
-static pascal OSErr
-mac_do_receive_drag (window, refcon, drag)
- WindowRef window;
- void *refcon;
- DragRef drag;
-{
- OSErr err;
- int num_types, i;
- Lisp_Object rest, str;
- FlavorType *types;
- AppleEvent apple_event;
- Point mouse_pos;
- SInt16 modifiers;
-
- if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
- return dragNotAcceptedErr;
-
- num_types = 0;
- for (rest = Vmac_dnd_known_types; CONSP (rest); rest = XCDR (rest))
- {
- str = XCAR (rest);
- if (STRINGP (str) && SBYTES (str) == 4)
- num_types++;
- }
-
- types = xmalloc (sizeof (FlavorType) * num_types);
- i = 0;
- for (rest = Vmac_dnd_known_types; CONSP (rest); rest = XCDR (rest))
- {
- str = XCAR (rest);
- if (STRINGP (str) && SBYTES (str) == 4)
- types[i++] = EndianU32_BtoN (*((UInt32 *) SDATA (str)));
- }
-
- err = create_apple_event_from_drag_ref (drag, num_types, types,
- &apple_event);
- xfree (types);
-
- if (err == noErr)
- err = GetDragMouse (drag, &mouse_pos, NULL);
- if (err == noErr)
- {
- GlobalToLocal (&mouse_pos);
- err = GetDragModifiers (drag, NULL, NULL, &modifiers);
- }
- if (err == noErr)
- {
- UInt32 key_modifiers = modifiers;
-
- err = AEPutParamPtr (&apple_event, kEventParamKeyModifiers,
- typeUInt32, &key_modifiers, sizeof (UInt32));
- }
-
- if (err == noErr)
- {
- mac_store_drag_event (window, mouse_pos, 0, &apple_event);
- AEDisposeDesc (&apple_event);
- mac_wakeup_from_rne ();
- return noErr;
- }
- else
- return dragNotAcceptedErr;
-}
+Lisp_Object Vmac_dnd_known_types;
#endif /* TARGET_API_MAC_CARBON */
-OSErr
-install_drag_handler (window)
- WindowRef window;
-{
- OSErr err = noErr;
-
-#if TARGET_API_MAC_CARBON
- if (mac_do_track_dragUPP == NULL)
- mac_do_track_dragUPP = NewDragTrackingHandlerUPP (mac_do_track_drag);
- if (mac_do_receive_dragUPP == NULL)
- mac_do_receive_dragUPP = NewDragReceiveHandlerUPP (mac_do_receive_drag);
-
- err = InstallTrackingHandler (mac_do_track_dragUPP, window, NULL);
- if (err == noErr)
- err = InstallReceiveHandler (mac_do_receive_dragUPP, window, NULL);
-#endif
-
- return err;
-}
-
-void
-remove_drag_handler (window)
- WindowRef window;
-{
-#if TARGET_API_MAC_CARBON
- if (mac_do_track_dragUPP)
- RemoveTrackingHandler (mac_do_track_dragUPP, window);
- if (mac_do_receive_dragUPP)
- RemoveReceiveHandler (mac_do_receive_dragUPP, window);
-#endif
-}
-
\f
/***********************************************************************
Services menu support
***********************************************************************/
#ifdef MAC_OSX
-void
-init_service_handler ()
-{
- static const EventTypeSpec specs[] =
- {{kEventClassService, kEventServiceGetTypes},
- {kEventClassService, kEventServiceCopy},
- {kEventClassService, kEventServicePaste},
- {kEventClassService, kEventServicePerform}};
- InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event),
- GetEventTypeCount (specs), specs, NULL, NULL);
-}
-
-extern OSStatus mac_store_service_event P_ ((EventRef));
-
-static OSStatus
-copy_scrap_flavor_data (from_scrap, to_scrap, flavor_type)
- ScrapRef from_scrap, to_scrap;
- ScrapFlavorType flavor_type;
-{
- OSStatus err;
- Size size, size_allocated;
- char *buf = NULL;
-
- err = GetScrapFlavorSize (from_scrap, flavor_type, &size);
- if (err == noErr)
- buf = xmalloc (size);
- while (buf)
- {
- size_allocated = size;
- err = GetScrapFlavorData (from_scrap, flavor_type, &size, buf);
- if (err != noErr)
- {
- xfree (buf);
- buf = NULL;
- }
- else if (size_allocated < size)
- buf = xrealloc (buf, size);
- else
- break;
- }
- if (err == noErr)
- {
- if (buf == NULL)
- err = memFullErr;
- else
- {
- err = PutScrapFlavor (to_scrap, flavor_type, kScrapFlavorMaskNone,
- size, buf);
- xfree (buf);
- }
- }
-
- return err;
-}
-
-static OSStatus
-mac_handle_service_event (call_ref, event, data)
- EventHandlerCallRef call_ref;
- EventRef event;
- void *data;
-{
- OSStatus err = noErr;
- ScrapRef cur_scrap, specific_scrap;
- UInt32 event_kind = GetEventKind (event);
- CFMutableArrayRef copy_types, paste_types;
- CFStringRef type;
- Lisp_Object rest;
- ScrapFlavorType flavor_type;
-
- /* Check if Vmac_service_selection is a valid selection that has a
- corresponding scrap. */
- if (!SYMBOLP (Vmac_service_selection))
- err = eventNotHandledErr;
- else
- err = get_scrap_from_symbol (Vmac_service_selection, 0, &cur_scrap);
- if (!(err == noErr && cur_scrap))
- return eventNotHandledErr;
-
- switch (event_kind)
- {
- case kEventServiceGetTypes:
- /* Set paste types. */
- err = GetEventParameter (event, kEventParamServicePasteTypes,
- typeCFMutableArrayRef, NULL,
- sizeof (CFMutableArrayRef), NULL,
- &paste_types);
- if (err != noErr)
- break;
-
- for (rest = Vselection_converter_alist; CONSP (rest);
- rest = XCDR (rest))
- if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))
- && (flavor_type =
- get_flavor_type_from_symbol (XCAR (XCAR (rest)))))
- {
- type = CreateTypeStringWithOSType (flavor_type);
- if (type)
- {
- CFArrayAppendValue (paste_types, type);
- CFRelease (type);
- }
- }
-
- /* Set copy types. */
- err = GetEventParameter (event, kEventParamServiceCopyTypes,
- typeCFMutableArrayRef, NULL,
- sizeof (CFMutableArrayRef), NULL,
- ©_types);
- if (err != noErr)
- break;
-
- if (NILP (Fx_selection_owner_p (Vmac_service_selection)))
- break;
- else
- goto copy_all_flavors;
-
- case kEventServiceCopy:
- err = GetEventParameter (event, kEventParamScrapRef,
- typeScrapRef, NULL,
- sizeof (ScrapRef), NULL, &specific_scrap);
- if (err != noErr
- || NILP (Fx_selection_owner_p (Vmac_service_selection)))
- {
- err = eventNotHandledErr;
- break;
- }
-
- copy_all_flavors:
- {
- UInt32 count, i;
- ScrapFlavorInfo *flavor_info = NULL;
- ScrapFlavorFlags flags;
-
- err = GetScrapFlavorCount (cur_scrap, &count);
- if (err == noErr)
- flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count);
- err = GetScrapFlavorInfoList (cur_scrap, &count, flavor_info);
- if (err != noErr)
- {
- xfree (flavor_info);
- flavor_info = NULL;
- }
- if (flavor_info == NULL)
- break;
-
- for (i = 0; i < count; i++)
- {
- flavor_type = flavor_info[i].flavorType;
- err = GetScrapFlavorFlags (cur_scrap, flavor_type, &flags);
- if (err == noErr && !(flags & kScrapFlavorMaskSenderOnly))
- {
- if (event_kind == kEventServiceCopy)
- err = copy_scrap_flavor_data (cur_scrap, specific_scrap,
- flavor_type);
- else /* event_kind == kEventServiceGetTypes */
- {
- type = CreateTypeStringWithOSType (flavor_type);
- if (type)
- {
- CFArrayAppendValue (copy_types, type);
- CFRelease (type);
- }
- }
- }
- }
- xfree (flavor_info);
- }
- break;
-
- case kEventServicePaste:
- case kEventServicePerform:
- {
- int data_exists_p = 0;
-
- err = GetEventParameter (event, kEventParamScrapRef, typeScrapRef,
- NULL, sizeof (ScrapRef), NULL,
- &specific_scrap);
- if (err == noErr)
- err = clear_scrap (&cur_scrap);
- if (err == noErr)
- for (rest = Vselection_converter_alist; CONSP (rest);
- rest = XCDR (rest))
- {
- if (! (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))))
- continue;
- flavor_type = get_flavor_type_from_symbol (XCAR (XCAR (rest)));
- if (flavor_type == 0)
- continue;
- err = copy_scrap_flavor_data (specific_scrap, cur_scrap,
- flavor_type);
- if (err == noErr)
- data_exists_p = 1;
- }
- if (!data_exists_p)
- err = eventNotHandledErr;
- else
- err = mac_store_service_event (event);
- }
- break;
- }
-
- if (err != noErr)
- err = eventNotHandledErr;
- return err;
-}
+/* Selection name for communication via Services menu. */
+Lisp_Object Vmac_service_selection;
#endif
-
void
syms_of_macselect ()
{
DEFVAR_LISP ("mac-dnd-known-types", &Vmac_dnd_known_types,
doc: /* The types accepted by default for dropped data.
The types are chosen in the order they appear in the list. */);
- Vmac_dnd_known_types = list4 (build_string ("hfs "), build_string ("utxt"),
- build_string ("TEXT"), build_string ("TIFF"));
-#ifdef MAC_OSX
- Vmac_dnd_known_types = Fcons (build_string ("furl"), Vmac_dnd_known_types);
-#endif
+ Vmac_dnd_known_types = mac_dnd_default_known_types ();
#endif
#ifdef MAC_OSX
#include <alloca.h>
#endif
-#if TARGET_API_MAC_CARBON
-/* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
- obtain events from the event queue. If set to 0, WaitNextEvent is
- used instead. */
-#define USE_CARBON_EVENTS 1
-#else /* not TARGET_API_MAC_CARBON */
+#if !TARGET_API_MAC_CARBON
#include <Quickdraw.h>
#include <ToolUtils.h>
#include <Sound.h>
rendering which may anti-alias the text. */
int mac_use_core_graphics;
-
-/* Non-zero means that a HELP_EVENT has been generated since Emacs
- start. */
-
-static int any_help_event_p;
-
-/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
-static Lisp_Object last_window;
-
/* Non-zero means make use of UNDERLINE_POSITION font properties.
(Not yet supported.) */
int x_use_underline_position_properties;
/* Where the mouse was last time we reported a mouse event. */
-static Rect last_mouse_glyph;
-static FRAME_PTR last_mouse_glyph_frame;
+Rect last_mouse_glyph;
+FRAME_PTR last_mouse_glyph_frame;
/* The scroll bar in which the last X motion event occurred.
this to Qnil, to tell XTmouse_position to return an ordinary motion
event. */
-static Lisp_Object last_mouse_scroll_bar;
+Lisp_Object last_mouse_scroll_bar;
/* This is a hack. We would really prefer that XTmouse_position would
return the time associated with the position it returns, but there
of the last movement we received, and return that in hopes that
it's somewhat accurate. */
-static Time last_mouse_movement_time;
+Time last_mouse_movement_time;
struct scroll_bar *tracked_scroll_bar = NULL;
events. */
#ifdef __STDC__
-static int volatile input_signal_count;
+int volatile input_signal_count;
#else
-static int input_signal_count;
+int input_signal_count;
#endif
extern Lisp_Object Vsystem_name;
QDGlobals qd; /* QuickDraw global information structure. */
#endif
-#define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
-
struct mac_display_info *mac_display_info_for_display (Display *);
static void x_update_window_end P_ ((struct window *, int, int));
int x_catch_errors P_ ((Display *));
static void frame_highlight P_ ((struct frame *));
static void frame_unhighlight P_ ((struct frame *));
static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
-static void mac_focus_changed P_ ((int, struct mac_display_info *,
- struct frame *, struct input_event *));
-static void x_detect_focus_change P_ ((struct mac_display_info *,
- const EventRecord *,
- struct input_event *));
static void XTframe_rehighlight P_ ((struct frame *));
static void x_frame_rehighlight P_ ((struct x_display_info *));
static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
enum text_cursor_kinds));
static void x_clip_to_row P_ ((struct window *, struct glyph_row *, int, GC));
-static void x_flush P_ ((struct frame *f));
static void x_update_begin P_ ((struct frame *));
static void x_update_window_begin P_ ((struct window *));
static void x_after_update_window_line P_ ((struct glyph_row *));
-static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
- enum scroll_bar_part *,
- Lisp_Object *, Lisp_Object *,
- unsigned long *));
-static int is_emacs_window P_ ((WindowPtr));
static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
static void XSetFont P_ ((Display *, GC, XFontStruct *));
+extern void mac_toolbox_initialize P_ ((void));
+extern void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
+ enum scroll_bar_part *,
+ Lisp_Object *, Lisp_Object *,
+ unsigned long *));
+#if USE_CG_DRAWING
+extern void mac_flush_display_optional P_ ((struct frame *));
+#endif
+
#define GC_FORE_COLOR(gc) (&(gc)->fore_color)
#define GC_BACK_COLOR(gc) (&(gc)->back_color)
#define GC_FONT(gc) ((gc)->xgcv.font)
(gc)->cg_fore_color)
#if USE_CG_DRAWING
-#define FRAME_CG_CONTEXT(f) ((f)->output_data.mac->cg_context)
-
/* Fringe bitmaps. */
static int max_fringe_bmp = 0;
static CGImageRef *fringe_bmp = 0;
-static CGColorSpaceRef mac_cg_color_space_rgb;
+CGColorSpaceRef mac_cg_color_space_rgb;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
static CGColorRef mac_cg_color_black;
#endif
if (CGColorGetTypeID != NULL)
#endif
{
- float rgba[] = {0.0f, 0.0f, 0.0f, 1.0f};
+ CGFloat rgba[] = {0.0f, 0.0f, 0.0f, 1.0f};
mac_cg_color_black = CGColorCreate (mac_cg_color_space_rgb, rgba);
}
#endif
}
-
-static CGContextRef
-mac_begin_cg_clip (f, gc)
- struct frame *f;
- GC gc;
-{
- CGContextRef context = FRAME_CG_CONTEXT (f);
-
- if (!context)
- {
- QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
- FRAME_CG_CONTEXT (f) = context;
- }
-
- CGContextSaveGState (context);
- CGContextTranslateCTM (context, 0, FRAME_PIXEL_HEIGHT (f));
- CGContextScaleCTM (context, 1, -1);
- if (gc && gc->n_clip_rects)
- CGContextClipToRects (context, gc->clip_rects, gc->n_clip_rects);
-
- return context;
-}
-
-static void
-mac_end_cg_clip (f)
- struct frame *f;
-{
- CGContextRestoreGState (FRAME_CG_CONTEXT (f));
-}
-
-void
-mac_prepare_for_quickdraw (f)
- struct frame *f;
-{
- if (f == NULL)
- {
- Lisp_Object rest, frame;
- FOR_EACH_FRAME (rest, frame)
- if (FRAME_MAC_P (XFRAME (frame)))
- mac_prepare_for_quickdraw (XFRAME (frame));
- }
- else
- {
- CGContextRef context = FRAME_CG_CONTEXT (f);
-
- if (context)
- {
- CGContextSynchronize (context);
- QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)),
- &FRAME_CG_CONTEXT (f));
- }
- }
-}
-#endif
-
-static RgnHandle saved_port_clip_region = NULL;
-
-static void
-mac_begin_clip (gc)
- GC gc;
-{
- static RgnHandle new_region = NULL;
-
- if (saved_port_clip_region == NULL)
- saved_port_clip_region = NewRgn ();
- if (new_region == NULL)
- new_region = NewRgn ();
-
- if (gc->n_clip_rects)
- {
- GetClip (saved_port_clip_region);
- SectRgn (saved_port_clip_region, gc->clip_region, new_region);
- SetClip (new_region);
- }
-}
-
-static void
-mac_end_clip (gc)
- GC gc;
-{
- if (gc->n_clip_rects)
- SetClip (saved_port_clip_region);
-}
-
+#endif /* USE_CG_DRAWING */
/* X display function emulation */
-void
-XFreePixmap (display, pixmap)
- Display *display; /* not used */
- Pixmap pixmap;
-{
- DisposeGWorld (pixmap);
-}
-
-
/* Mac version of XDrawLine. */
static void
{
#if USE_CG_DRAWING
CGContextRef context;
- float gx1 = x1, gy1 = y1, gx2 = x2, gy2 = y2;
+ CGFloat gx1 = x1, gy1 = y1, gx2 = x2, gy2 = y2;
if (y1 != y2)
gx1 += 0.5f, gx2 += 0.5f;
x2--;
}
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+ mac_begin_clip (f, gc);
RGBForeColor (GC_FORE_COLOR (gc));
-
- mac_begin_clip (gc);
MoveTo (x1, y1);
LineTo (x2, y2);
- mac_end_clip (gc);
+ mac_end_clip (f, gc);
#endif
}
GC gc;
int x1, y1, x2, y2;
{
+#if USE_MAC_IMAGE_IO
+ CGContextRef context;
+ XImagePtr ximg = p;
+ CGColorSpaceRef color_space;
+ CGImageAlphaInfo alpha_info;
+ CGFloat gx1 = x1, gy1 = y1, gx2 = x2, gy2 = y2;
+
+ if (y1 != y2)
+ gx1 += 0.5f, gx2 += 0.5f;
+ if (x1 != x2)
+ gy1 += 0.5f, gy2 += 0.5f;
+
+ if (ximg->bits_per_pixel == 32)
+ {
+ color_space = mac_cg_color_space_rgb;
+ alpha_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
+ }
+ else
+ {
+ color_space = NULL;
+ alpha_info = kCGImageAlphaOnly;
+ }
+ context = CGBitmapContextCreate (ximg->data, ximg->width, ximg->height, 8,
+ ximg->bytes_per_line, color_space,
+ alpha_info);
+ if (ximg->bits_per_pixel == 32)
+ CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
+ else
+ CGContextSetGrayStrokeColor (context, gc->xgcv.foreground / 255.0f, 1.0);
+ CGContextMoveToPoint (context, gx1, gy1);
+ CGContextAddLineToPoint (context, gx2, gy2);
+ CGContextClosePath (context);
+ CGContextStrokePath (context);
+ CGContextRelease (context);
+#else
CGrafPtr old_port;
GDHandle old_gdh;
UnlockPixels (GetGWorldPixMap (p));
SetGWorld (old_port, old_gdh);
+#endif
}
context = mac_begin_cg_clip (f, gc);
CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
- CGContextFillRect (context, CGRectMake (x, y, width, height));
+ CGContextFillRect (context, mac_rect_make (f, x, y, width, height));
mac_end_cg_clip (f);
#else
Rect r;
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+ mac_begin_clip (f, gc);
RGBBackColor (GC_BACK_COLOR (gc));
SetRect (&r, x, y, x + width, y + height);
-
- mac_begin_clip (gc);
EraseRect (&r);
- mac_end_clip (gc);
-
RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+ mac_end_clip (f, gc);
#endif
}
CGContextFillRect (context, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f),
FRAME_PIXEL_HEIGHT (f)));
mac_end_cg_clip (f);
-#else
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+#else /* !USE_CG_DRAWING */
+ mac_begin_clip (f, NULL);
RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
-
#if TARGET_API_MAC_CARBON
{
Rect r;
#else /* not TARGET_API_MAC_CARBON */
EraseRect (&(FRAME_MAC_WINDOW (f)->portRect));
#endif /* not TARGET_API_MAC_CARBON */
+ mac_end_clip (f, NULL);
#endif
}
int dest_x, dest_y, overlay_p;
{
CGContextRef context;
- float port_height = FRAME_PIXEL_HEIGHT (f);
- CGRect dest_rect = CGRectMake (dest_x, dest_y, width, height);
+ CGRect dest_rect, bounds;
context = mac_begin_cg_clip (f, gc);
+ dest_rect = mac_rect_make (f, dest_x, dest_y, width, height);
+ bounds = mac_rect_make (f, dest_x - src_x, dest_y - src_y,
+ CGImageGetWidth (image), CGImageGetHeight (image));
if (!overlay_p)
{
CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
CGContextFillRect (context, dest_rect);
}
CGContextClipToRect (context, dest_rect);
+ CGContextTranslateCTM (context,
+ CGRectGetMinX (bounds), CGRectGetMaxY (bounds));
CGContextScaleCTM (context, 1, -1);
- CGContextTranslateCTM (context, 0, -port_height);
if (CGImageIsMask (image))
CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
- CGContextDrawImage (context,
- CGRectMake (dest_x - src_x,
- port_height - (dest_y - src_y
- + CGImageGetHeight (image)),
- CGImageGetWidth (image),
- CGImageGetHeight (image)),
- image);
+ bounds.origin = CGPointZero;
+ CGContextDrawImage (context, bounds, image);
mac_end_cg_clip (f);
}
bitmap.baseAddr = (char *)bits;
SetRect (&(bitmap.bounds), 0, 0, width, height);
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+ mac_begin_clip (f, gc);
RGBForeColor (GC_FORE_COLOR (gc));
RGBBackColor (GC_BACK_COLOR (gc));
SetRect (&r, x, y, x + width, y + height);
-
- mac_begin_clip (gc);
#if TARGET_API_MAC_CARBON
{
CGrafPtr port;
CopyBits (&bitmap, &(FRAME_MAC_WINDOW (f)->portBits), &(bitmap.bounds), &r,
overlay_p ? srcOr : srcCopy, 0);
#endif /* not TARGET_API_MAC_CARBON */
- mac_end_clip (gc);
-
RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+ mac_end_clip (f, gc);
}
#endif /* !USE_CG_DRAWING */
Pixmap
XCreatePixmap (display, w, width, height, depth)
- Display *display; /* not used */
- WindowPtr w;
+ Display *display;
+ Window w;
unsigned int width, height;
unsigned int depth;
{
+#if USE_MAC_IMAGE_IO
+ XImagePtr ximg;
+
+ ximg = xmalloc (sizeof (*ximg));
+ ximg->width = width;
+ ximg->height = height;
+ ximg->bits_per_pixel = depth == 1 ? 8 : 32;
+ ximg->bytes_per_line = width * (ximg->bits_per_pixel / 8);
+ ximg->data = xmalloc (ximg->bytes_per_line * height);
+ return ximg;
+#else
Pixmap pixmap;
Rect r;
QDErr err;
+#ifdef MAC_OS8
SetPortWindowPort (w);
-
+#endif
SetRect (&r, 0, 0, width, height);
#if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING
if (depth == 1)
if (err != noErr)
return NULL;
return pixmap;
+#endif
}
Pixmap
XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
- Display *display; /* not used */
- WindowPtr w;
+ Display *display;
+ Window w;
char *data;
unsigned int width, height;
unsigned long fg, bg;
{
Pixmap pixmap;
BitMap bitmap;
+#if USE_MAC_IMAGE_IO
+ CGDataProviderRef provider;
+ CGImageRef image_mask;
+ CGContextRef context;
+
+ pixmap = XCreatePixmap (display, w, width, height, depth);
+ if (pixmap == NULL)
+ return NULL;
+
+ mac_create_bitmap_from_bitmap_data (&bitmap, data, width, height);
+ provider = CGDataProviderCreateWithData (NULL, bitmap.baseAddr,
+ bitmap.rowBytes * height, NULL);
+ image_mask = CGImageMaskCreate (width, height, 1, 1, bitmap.rowBytes,
+ provider, NULL, 0);
+ CGDataProviderRelease (provider);
+
+ context = CGBitmapContextCreate (pixmap->data, width, height, 8,
+ pixmap->bytes_per_line,
+ mac_cg_color_space_rgb,
+ kCGImageAlphaNoneSkipFirst
+ | kCGBitmapByteOrder32Host);
+
+ CG_SET_FILL_COLOR (context, fg);
+ CGContextFillRect (context, CGRectMake (0, 0, width, height));
+ CG_SET_FILL_COLOR (context, bg);
+ CGContextDrawImage (context, CGRectMake (0, 0, width, height), image_mask);
+ CGContextRelease (context);
+ CGImageRelease (image_mask);
+#else
CGrafPtr old_port;
GDHandle old_gdh;
- static GC gc = NULL; /* not reentrant */
+ static GC gc = NULL;
if (gc == NULL)
gc = XCreateGC (display, w, 0, NULL);
#endif /* not TARGET_API_MAC_CARBON */
UnlockPixels (GetGWorldPixMap (pixmap));
SetGWorld (old_port, old_gdh);
+#endif
mac_free_bitmap (&bitmap);
return pixmap;
}
+void
+XFreePixmap (display, pixmap)
+ Display *display;
+ Pixmap pixmap;
+{
+#if USE_MAC_IMAGE_IO
+ if (pixmap)
+ {
+ if (pixmap->data)
+ xfree (pixmap->data);
+ xfree (pixmap);
+ }
+#else
+ DisposeGWorld (pixmap);
+#endif
+}
+
+
/* Mac replacement for XFillRectangle. */
static void
context = mac_begin_cg_clip (f, gc);
CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
- CGContextFillRect (context, CGRectMake (x, y, width, height));
+ CGContextFillRect (context, mac_rect_make (f, x, y, width, height));
mac_end_cg_clip (f);
#else
Rect r;
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+ mac_begin_clip (f, gc);
RGBForeColor (GC_FORE_COLOR (gc));
SetRect (&r, x, y, x + width, y + height);
-
- mac_begin_clip (gc);
PaintRect (&r); /* using foreground color of gc */
- mac_end_clip (gc);
+ mac_end_clip (f, gc);
#endif
}
{
#if USE_CG_DRAWING
CGContextRef context;
+ CGRect rect;
context = mac_begin_cg_clip (f, gc);
CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
- CGContextStrokeRect (context,
- CGRectMake (x + 0.5f, y + 0.5f, width, height));
+ rect = mac_rect_make (f, x, y, width + 1, height + 1);
+ CGContextStrokeRect (context, CGRectInset (rect, 0.5f, 0.5f));
mac_end_cg_clip (f);
#else
Rect r;
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+ mac_begin_clip (f, gc);
RGBForeColor (GC_FORE_COLOR (gc));
SetRect (&r, x, y, x + width + 1, y + height + 1);
-
- mac_begin_clip (gc);
FrameRect (&r); /* using foreground color of gc */
- mac_end_clip (gc);
+ mac_end_clip (f, gc);
+#endif
+}
+
+
+static void
+mac_invert_rectangle (f, x, y, width, height)
+ struct frame *f;
+ int x, y;
+ unsigned int width, height;
+{
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 && MAC_OS_X_VERSION_MIN_REQUIRED >= 1020
+ if (CGContextSetBlendMode != NULL)
+#endif
+ {
+ CGContextRef context;
+
+ context = mac_begin_cg_clip (f, NULL);
+ CGContextSetRGBFillColor (context, 1.0f, 1.0f, 1.0f, 1.0f);
+ CGContextSetBlendMode (context, kCGBlendModeDifference);
+ CGContextFillRect (context, mac_rect_make (f, x, y, width, height));
+ mac_end_cg_clip (f);
+ }
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 && MAC_OS_X_VERSION_MIN_REQUIRED >= 1020
+ else /* CGContextSetBlendMode == NULL */
+#endif
+#endif /* USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 */
+#if !USE_CG_DRAWING || MAC_OS_X_VERSION_MAX_ALLOWED < 1040 || (MAC_OS_X_VERSION_MIN_REQUIRED < 1040 && MAC_OS_X_VERSION_MIN_REQUIRED >= 1020)
+ {
+ Rect r;
+
+ mac_begin_clip (f, NULL);
+ SetRect (&r, x, y, x + width, y + height);
+ InvertRect (&r);
+ mac_end_clip (f, NULL);
+ }
#endif
}
ATSUTextLayout *text_layout;
{
OSStatus err;
- static ATSUTextLayout saved_text_layout = NULL; /* not reentrant */
+ static ATSUTextLayout saved_text_layout = NULL;
if (saved_text_layout == NULL)
{
err = ATSUSetLayoutControls (saved_text_layout,
sizeof (tags) / sizeof (tags[0]),
tags, sizes, values);
- /* XXX: Should we do this? */
if (err == noErr)
err = ATSUSetTransientFontMatching (saved_text_layout, true);
}
*text_layout = saved_text_layout;
return err;
}
-#endif
-
-
-static void
-mac_invert_rectangle (f, x, y, width, height)
- struct frame *f;
- int x, y;
- unsigned int width, height;
-{
- Rect r;
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
- SetRect (&r, x, y, x + width, y + height);
-
- InvertRect (&r);
-}
static void
-mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width,
- overstrike_p, bytes_per_char)
+mac_draw_image_string_atsui (f, gc, x, y, buf, nchars, bg_width,
+ overstrike_p, bytes_per_char)
struct frame *f;
GC gc;
int x, y;
char *buf;
int nchars, bg_width, overstrike_p, bytes_per_char;
{
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
-#if USE_ATSUI
- if (GC_FONT (gc)->mac_style)
- {
- OSStatus err;
- ATSUTextLayout text_layout;
+ OSStatus err;
+ ATSUTextLayout text_layout;
- xassert (bytes_per_char == 2);
+ xassert (bytes_per_char == 2);
#ifndef WORDS_BIG_ENDIAN
- {
- int i;
- UniChar *text = (UniChar *)buf;
+ {
+ int i;
+ UniChar *text = (UniChar *)buf;
- for (i = 0; i < nchars; i++)
- text[i] = EndianU16_BtoN (text[i]);
- }
+ for (i = 0; i < nchars; i++)
+ text[i] = EndianU16_BtoN (text[i]);
+ }
#endif
- err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf,
- nchars,
- GC_FONT (gc)->mac_style,
- &text_layout);
- if (err != noErr)
- return;
+ err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf,
+ nchars,
+ GC_FONT (gc)->mac_style,
+ &text_layout);
+ if (err != noErr)
+ return;
#ifdef MAC_OSX
- if (!mac_use_core_graphics)
- {
-#endif
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
+ if (!mac_use_core_graphics)
+ {
#endif
- mac_begin_clip (gc);
- RGBForeColor (GC_FORE_COLOR (gc));
- if (bg_width)
- {
- Rect r;
+ mac_begin_clip (f, gc);
+ RGBForeColor (GC_FORE_COLOR (gc));
+ if (bg_width)
+ {
+ Rect r;
- SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
- x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
- RGBBackColor (GC_BACK_COLOR (gc));
- EraseRect (&r);
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
- }
- MoveTo (x, y);
+ SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
+ x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
+ RGBBackColor (GC_BACK_COLOR (gc));
+ EraseRect (&r);
+ RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+ }
+ MoveTo (x, y);
+ ATSUDrawText (text_layout,
+ kATSUFromTextBeginning, kATSUToTextEnd,
+ kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
+ if (overstrike_p)
+ {
+ MoveTo (x + 1, y);
ATSUDrawText (text_layout,
kATSUFromTextBeginning, kATSUToTextEnd,
kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
- if (overstrike_p)
- {
- MoveTo (x + 1, y);
- ATSUDrawText (text_layout,
- kATSUFromTextBeginning, kATSUToTextEnd,
- kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
- }
- mac_end_clip (gc);
-#ifdef MAC_OSX
}
- else
- {
- CGrafPtr port;
- static CGContextRef context;
- float port_height = FRAME_PIXEL_HEIGHT (f);
- static const ATSUAttributeTag tags[] = {kATSUCGContextTag};
- static const ByteCount sizes[] = {sizeof (CGContextRef)};
- static const ATSUAttributeValuePtr values[] = {&context};
+ mac_end_clip (f, gc);
+#ifdef MAC_OSX
+ }
+ else
+ {
+ static CGContextRef context;
+ static const ATSUAttributeTag tags[] = {kATSUCGContextTag};
+ static const ByteCount sizes[] = {sizeof (CGContextRef)};
+ static const ATSUAttributeValuePtr values[] = {&context};
#if USE_CG_DRAWING
- context = mac_begin_cg_clip (f, gc);
+ context = mac_begin_cg_clip (f, gc);
#else
- GetPort (&port);
- QDBeginCGContext (port, &context);
- if (gc->n_clip_rects || bg_width)
- {
- CGContextTranslateCTM (context, 0, port_height);
- CGContextScaleCTM (context, 1, -1);
- if (gc->n_clip_rects)
- CGContextClipToRects (context, gc->clip_rects,
- gc->n_clip_rects);
-#endif
- if (bg_width)
- {
- CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
- CGContextFillRect
- (context,
- CGRectMake (x, y - FONT_BASE (GC_FONT (gc)),
- bg_width, FONT_HEIGHT (GC_FONT (gc))));
- }
- CGContextScaleCTM (context, 1, -1);
- CGContextTranslateCTM (context, 0, -port_height);
-#if !USE_CG_DRAWING
- }
+ CGrafPtr port;
+
+ GetPort (&port);
+ QDBeginCGContext (port, &context);
+ CGContextTranslateCTM (context, 0, FRAME_PIXEL_HEIGHT (f));
+ if (gc->n_clip_rects || bg_width)
+ {
+ CGContextScaleCTM (context, 1, -1);
+ if (gc->n_clip_rects)
+ CGContextClipToRects (context, gc->clip_rects,
+ gc->n_clip_rects);
#endif
- CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
- err = ATSUSetLayoutControls (text_layout,
- sizeof (tags) / sizeof (tags[0]),
- tags, sizes, values);
- if (err == noErr)
+ if (bg_width)
{
- ATSUDrawText (text_layout,
- kATSUFromTextBeginning, kATSUToTextEnd,
- Long2Fix (x), Long2Fix (port_height - y));
- if (overstrike_p)
- ATSUDrawText (text_layout,
- kATSUFromTextBeginning, kATSUToTextEnd,
- Long2Fix (x + 1), Long2Fix (port_height - y));
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
+ CGContextFillRect (context,
+ mac_rect_make (f,
+ x, y - FONT_BASE (GC_FONT (gc)),
+ bg_width,
+ FONT_HEIGHT (GC_FONT (gc))));
}
+ CGContextScaleCTM (context, 1, -1);
+#if !USE_CG_DRAWING
+ }
+#endif
+ CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
+ err = ATSUSetLayoutControls (text_layout,
+ sizeof (tags) / sizeof (tags[0]),
+ tags, sizes, values);
+ if (err == noErr)
+ {
+ ATSUDrawText (text_layout,
+ kATSUFromTextBeginning, kATSUToTextEnd,
+ Long2Fix (x), Long2Fix (-y));
+ if (overstrike_p)
+ ATSUDrawText (text_layout,
+ kATSUFromTextBeginning, kATSUToTextEnd,
+ Long2Fix (x + 1), Long2Fix (-y));
+ }
#if USE_CG_DRAWING
- mac_end_cg_clip (f);
- context = NULL;
+ mac_end_cg_clip (f);
+ context = NULL;
#else
- CGContextSynchronize (context);
- QDEndCGContext (port, &context);
+ CGContextSynchronize (context);
+ QDEndCGContext (port, &context);
#endif
#if 0
- /* This doesn't work on Mac OS X 10.1. */
- ATSUClearLayoutControls (text_layout,
- sizeof (tags) / sizeof (tags[0]), tags);
+ /* This doesn't work on Mac OS X 10.1. */
+ ATSUClearLayoutControls (text_layout,
+ sizeof (tags) / sizeof (tags[0]), tags);
#else
- ATSUSetLayoutControls (text_layout,
- sizeof (tags) / sizeof (tags[0]),
- tags, sizes, values);
+ ATSUSetLayoutControls (text_layout,
+ sizeof (tags) / sizeof (tags[0]),
+ tags, sizes, values);
#endif
- }
-#endif /* MAC_OSX */
}
- else
+#endif /* MAC_OSX */
+}
#endif /* USE_ATSUI */
- {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- UInt32 savedFlags;
- if (mac_use_core_graphics)
- savedFlags = SwapQDTextFlags (kQDUseCGTextRendering);
-#endif
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- mac_begin_clip (gc);
- RGBForeColor (GC_FORE_COLOR (gc));
-#ifdef MAC_OS8
- if (bg_width)
- {
- RGBBackColor (GC_BACK_COLOR (gc));
- TextMode (srcCopy);
- }
- else
- TextMode (srcOr);
+
+static void
+mac_draw_image_string_qd (f, gc, x, y, buf, nchars, bg_width,
+ overstrike_p, bytes_per_char)
+ struct frame *f;
+ GC gc;
+ int x, y;
+ char *buf;
+ int nchars, bg_width, overstrike_p, bytes_per_char;
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ UInt32 savedFlags;
+#endif
+
+ mac_begin_clip (f, gc);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ if (mac_use_core_graphics)
+ savedFlags = SwapQDTextFlags (kQDUseCGTextRendering);
+#endif
+ RGBForeColor (GC_FORE_COLOR (gc));
+#ifdef MAC_OS8
+ if (bg_width)
+ {
+ RGBBackColor (GC_BACK_COLOR (gc));
+ TextMode (srcCopy);
+ }
+ else
+ TextMode (srcOr);
#else
- /* We prefer not to use srcCopy text transfer mode on Mac OS X
- because:
- - Screen is double-buffered. (In srcCopy mode, a text is
- drawn into an offscreen graphics world first. So
- performance gain cannot be expected.)
- - It lowers rendering quality.
- - Some fonts leave garbage on cursor movement. */
- if (bg_width)
- {
- Rect r;
+ /* We prefer not to use srcCopy text transfer mode on Mac OS X
+ because:
+ - Screen is double-buffered. (In srcCopy mode, a text is drawn
+ into an offscreen graphics world first. So performance gain
+ cannot be expected.)
+ - It lowers rendering quality.
+ - Some fonts leave garbage on cursor movement. */
+ if (bg_width)
+ {
+ Rect r;
- RGBBackColor (GC_BACK_COLOR (gc));
- SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
- x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
- EraseRect (&r);
- }
- TextMode (srcOr);
+ RGBBackColor (GC_BACK_COLOR (gc));
+ SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
+ x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
+ EraseRect (&r);
+ }
+ TextMode (srcOr);
#endif
- TextFont (GC_FONT (gc)->mac_fontnum);
- TextSize (GC_FONT (gc)->mac_fontsize);
- TextFace (GC_FONT (gc)->mac_fontface);
- MoveTo (x, y);
+ TextFont (GC_FONT (gc)->mac_fontnum);
+ TextSize (GC_FONT (gc)->mac_fontsize);
+ TextFace (GC_FONT (gc)->mac_fontface);
+ MoveTo (x, y);
+ DrawText (buf, 0, nchars * bytes_per_char);
+ if (overstrike_p)
+ {
+ TextMode (srcOr);
+ MoveTo (x + 1, y);
DrawText (buf, 0, nchars * bytes_per_char);
- if (overstrike_p)
- {
- TextMode (srcOr);
- MoveTo (x + 1, y);
- DrawText (buf, 0, nchars * bytes_per_char);
- }
- if (bg_width)
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
- mac_end_clip (gc);
+ }
+ if (bg_width)
+ RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+ mac_end_clip (f, gc);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- if (mac_use_core_graphics)
- SwapQDTextFlags(savedFlags);
+ if (mac_use_core_graphics)
+ SwapQDTextFlags(savedFlags);
#endif
- }
+}
+
+
+static INLINE void
+mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width,
+ overstrike_p, bytes_per_char)
+ struct frame *f;
+ GC gc;
+ int x, y;
+ char *buf;
+ int nchars, bg_width, overstrike_p, bytes_per_char;
+{
+#if USE_ATSUI
+ if (GC_FONT (gc)->mac_style)
+ mac_draw_image_string_atsui (f, gc, x, y, buf, nchars, bg_width,
+ overstrike_p, bytes_per_char);
+ else
+#endif /* USE_ATSUI */
+ mac_draw_image_string_qd (f, gc, x, y, buf, nchars, bg_width,
+ overstrike_p, bytes_per_char);
}
XChar2b *buf;
int nchars, bg_width, overstrike_p;
{
- CGrafPtr port;
- float port_height, gx, gy;
+ CGFloat gx, gy;
int i;
CGContextRef context;
CGGlyph *glyphs;
if (!mac_use_core_graphics || GC_FONT (gc)->cg_font == NULL)
return 0;
- port = GetWindowPort (FRAME_MAC_WINDOW (f));
- port_height = FRAME_PIXEL_HEIGHT (f);
gx = x;
- gy = port_height - y;
+ gy = -y;
glyphs = (CGGlyph *)buf;
advances = alloca (sizeof (CGSize) * nchars);
if (advances == NULL)
#if USE_CG_DRAWING
context = mac_begin_cg_clip (f, gc);
#else
- QDBeginCGContext (port, &context);
+ QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
+ CGContextTranslateCTM (context, 0, FRAME_PIXEL_HEIGHT (f));
if (gc->n_clip_rects || bg_width)
{
- CGContextTranslateCTM (context, 0, port_height);
CGContextScaleCTM (context, 1, -1);
if (gc->n_clip_rects)
CGContextClipToRects (context, gc->clip_rects, gc->n_clip_rects);
CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
CGContextFillRect
(context,
- CGRectMake (gx, y - FONT_BASE (GC_FONT (gc)),
- bg_width, FONT_HEIGHT (GC_FONT (gc))));
+ mac_rect_make (f, gx, y - FONT_BASE (GC_FONT (gc)),
+ bg_width, FONT_HEIGHT (GC_FONT (gc))));
}
CGContextScaleCTM (context, 1, -1);
- CGContextTranslateCTM (context, 0, -port_height);
#if !USE_CG_DRAWING
}
#endif
CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
CGContextSetFont (context, GC_FONT (gc)->cg_font);
CGContextSetFontSize (context, GC_FONT (gc)->mac_fontsize);
+ CGContextSetTextMatrix (context, CGAffineTransformIdentity);
if (GC_FONT (gc)->mac_fontsize <= cg_text_anti_aliasing_threshold)
CGContextSetShouldAntialias (context, false);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
}
}
#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- else
+ else /* CGContextShowGlyphsWithAdvances == NULL */
#endif
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
mac_end_cg_clip (f);
#else
CGContextSynchronize (context);
- QDEndCGContext (port, &context);
+ QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
#endif
return 1;
{
Rect src_r, dest_r;
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
+ mac_begin_clip (f, gc);
SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
ForeColor (blackColor);
BackColor (whiteColor);
- mac_begin_clip (gc);
LockPixels (GetGWorldPixMap (src));
#if TARGET_API_MAC_CARBON
{
&src_r, &dest_r, srcCopy, 0);
#endif /* not TARGET_API_MAC_CARBON */
UnlockPixels (GetGWorldPixMap (src));
- mac_end_clip (gc);
RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+
+ mac_end_clip (f, gc);
}
{
Rect src_r, dest_r;
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
+ mac_begin_clip (f, gc);
SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
ForeColor (blackColor);
BackColor (whiteColor);
- mac_begin_clip (gc);
LockPixels (GetGWorldPixMap (src));
LockPixels (GetGWorldPixMap (mask));
#if TARGET_API_MAC_CARBON
#endif /* not TARGET_API_MAC_CARBON */
UnlockPixels (GetGWorldPixMap (mask));
UnlockPixels (GetGWorldPixMap (src));
- mac_end_clip (gc);
RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+
+ mac_end_clip (f, gc);
}
#endif /* !USE_CG_DRAWING */
/* Mac replacement for XCopyArea: used only for scrolling. */
+#if TARGET_API_MAC_CARBON
+/* Defined in mactoolbox.c. */
+extern void mac_scroll_area P_ ((struct frame *, GC, int, int,
+ unsigned int, unsigned int, int, int));
+#else /* not TARGET_API_MAC_CARBON */
static void
mac_scroll_area (f, gc, src_x, src_y, width, height, dest_x, dest_y)
struct frame *f;
unsigned int width, height;
int dest_x, dest_y;
{
-#if TARGET_API_MAC_CARBON
- Rect src_r;
- RgnHandle dummy = NewRgn (); /* For avoiding update events. */
-
- SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- ScrollWindowRect (FRAME_MAC_WINDOW (f),
- &src_r, dest_x - src_x, dest_y - src_y,
- kScrollWindowNoOptions, dummy);
- DisposeRgn (dummy);
-#else /* not TARGET_API_MAC_CARBON */
Rect src_r, dest_r;
- WindowPtr w = FRAME_MAC_WINDOW (f);
+ WindowRef w = FRAME_MAC_WINDOW (f);
- SetPort (w);
+ mac_begin_clip (f, gc);
SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
color mapping in CopyBits. Otherwise, it will be slow. */
ForeColor (blackColor);
BackColor (whiteColor);
- mac_begin_clip (gc);
CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0);
- mac_end_clip (gc);
RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
-#endif /* not TARGET_API_MAC_CARBON */
+
+ mac_end_clip (f, gc);
}
+#endif /* not TARGET_API_MAC_CARBON */
/* Mac replacement for XChangeGC. */
}
else
{
- float rgba[4];
+ CGFloat rgba[4];
rgba[0] = gc->fore_color.red / 65535.0f;
rgba[1] = gc->fore_color.green / 65535.0f;
}
else
{
- float rgba[4];
+ CGFloat rgba[4];
rgba[0] = gc->back_color.red / 65535.0f;
rgba[1] = gc->back_color.green / 65535.0f;
/* Mac replacement for XSetClipRectangles. */
static void
-mac_set_clip_rectangles (display, gc, rectangles, n)
- Display *display;
+mac_set_clip_rectangles (f, gc, rectangles, n)
+ struct frame *f;
GC gc;
Rect *rectangles;
int n;
{
Rect *rect = rectangles + i;
- gc->clip_rects[i] = CGRectMake (rect->left, rect->top,
- rect->right - rect->left,
- rect->bottom - rect->top);
+ gc->clip_rects[i] = mac_rect_make (f, rect->left, rect->top,
+ rect->right - rect->left,
+ rect->bottom - rect->top);
}
#endif
}
/* Mac replacement for XSetClipMask. */
static INLINE void
-mac_reset_clip_rectangles (display, gc)
- Display *display;
+mac_reset_clip_rectangles (f, gc)
+ struct frame *f;
GC gc;
{
gc->n_clip_rects = 0;
}
-
-/* Mac replacement for XSetWindowBackground. */
-
-void
-XSetWindowBackground (display, w, color)
- Display *display;
- WindowPtr w;
- unsigned long color;
-{
-#if !TARGET_API_MAC_CARBON
- AuxWinHandle aw_handle;
- CTabHandle ctab_handle;
- ColorSpecPtr ct_table;
- short ct_size;
-#endif
- RGBColor bg_color;
-
- bg_color.red = RED16_FROM_ULONG (color);
- bg_color.green = GREEN16_FROM_ULONG (color);
- bg_color.blue = BLUE16_FROM_ULONG (color);
-
-#if TARGET_API_MAC_CARBON
- SetWindowContentColor (w, &bg_color);
-#else
- if (GetAuxWin (w, &aw_handle))
- {
- ctab_handle = (*aw_handle)->awCTable;
- HandToHand ((Handle *) &ctab_handle);
- ct_table = (*ctab_handle)->ctTable;
- ct_size = (*ctab_handle)->ctSize;
- while (ct_size > -1)
- {
- if (ct_table->value == 0)
- {
- ct_table->rgb = bg_color;
- CTabChanged (ctab_handle);
- SetWinColor (w, (WCTabHandle) ctab_handle);
- }
- ct_size--;
- }
- }
-#endif
-}
-
-/* Flush display of frame F, or of all frames if F is null. */
-
-static void
-x_flush (f)
- struct frame *f;
-{
-#if TARGET_API_MAC_CARBON
- BLOCK_INPUT;
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- if (f)
- QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f)), NULL);
- else
- QDFlushPortBuffer (GetQDGlobalsThePort (), NULL);
- UNBLOCK_INPUT;
-#endif
-}
-
-
/* Remove calls to XFlush by defining XFlush to an empty replacement.
Calls to XFlush should be unnecessary because the X output buffer
is flushed automatically as needed by calls to XPending,
#define XFlush(DISPLAY) (void) 0
-#if USE_CG_DRAWING
-static void
-mac_flush_display_optional (f)
- struct frame *f;
-{
- BLOCK_INPUT;
- mac_prepare_for_quickdraw (f);
- UNBLOCK_INPUT;
-}
-#endif
\f
/***********************************************************************
Starting and ending an update
x_update_begin (f)
struct frame *f;
{
-#if TARGET_API_MAC_CARBON
- /* During update of a frame, availability of input events is
- periodically checked with ReceiveNextEvent if
- redisplay-dont-pause is nil. That normally flushes window buffer
- changes for every check, and thus screen update looks waving even
- if no input is available. So we disable screen updates during
- update of a frame. */
BLOCK_INPUT;
- DisableScreenUpdates ();
+ mac_update_begin (f);
UNBLOCK_INPUT;
-#endif
}
FRAME_MAC_DISPLAY_INFO (f)->mouse_face_defer = 0;
BLOCK_INPUT;
-#if TARGET_API_MAC_CARBON
- EnableScreenUpdates ();
-#endif
+ mac_update_end (f);
XFlush (FRAME_MAC_DISPLAY (f));
UNBLOCK_INPUT;
}
dpyinfo->mouse_face_deferred_gc = 0;
UNBLOCK_INPUT;
}
+
+ mac_frame_up_to_date (f);
}
}
Display *display = FRAME_MAC_DISPLAY (f);
struct face *face = p->face;
int rowY;
+ int overlay_p = p->overlay_p;
+
+#ifdef MAC_OSX
+ if (!overlay_p)
+ {
+ int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
+
+#if 0 /* MAC_TODO: stipple */
+ /* In case the same realized face is used for fringes and
+ for something displayed in the text (e.g. face `region' on
+ mono-displays, the fill style may have been changed to
+ FillSolid in x_draw_glyph_string_background. */
+ if (face->stipple)
+ XSetFillStyle (FRAME_X_DISPLAY (f), face->gc, FillOpaqueStippled);
+ else
+ XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
+#endif
+
+ /* If the fringe is adjacent to the left (right) scroll bar of a
+ leftmost (rightmost, respectively) window, then extend its
+ background to the gap between the fringe and the bar. */
+ if ((WINDOW_LEFTMOST_P (w)
+ && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+ || (WINDOW_RIGHTMOST_P (w)
+ && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
+ {
+ int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
+
+ if (sb_width > 0)
+ {
+ int left = WINDOW_SCROLL_BAR_AREA_X (w);
+ int width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
+ * FRAME_COLUMN_WIDTH (f));
+
+ if (bx < 0
+ && (left + width == p->x
+ || p->x + p->wd == left))
+ {
+ /* Bitmap fills the fringe and we need background
+ extension. */
+ int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+
+ bx = p->x;
+ nx = p->wd;
+ by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
+ row->y));
+ ny = row->visible_height;
+ }
+
+ if (bx >= 0)
+ {
+ if (left + width == bx)
+ {
+ bx = left + sb_width;
+ nx += width - sb_width;
+ }
+ else if (bx + nx == left)
+ nx += width - sb_width;
+ }
+ }
+ }
+
+ if (bx >= 0)
+ {
+ mac_erase_rectangle (f, face->gc, bx, by, nx, ny);
+ /* The fringe background has already been filled. */
+ overlay_p = 1;
+ }
+
+#if 0 /* MAC_TODO: stipple */
+ if (!face->stipple)
+ XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
+#endif
+ }
+#endif /* MAC_OSX */
/* Must clip because of partially visible lines. */
rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
else
x_clip_to_row (w, row, -1, face->gc);
+#ifndef MAC_OSX
if (p->bx >= 0 && !p->overlay_p)
{
#if 0 /* MAC_TODO: stipple */
XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
#endif
}
+#endif /* !MAC_OSX */
if (p->which
#if USE_CG_DRAWING
: face->foreground));
#if USE_CG_DRAWING
mac_draw_cg_image (fringe_bmp[p->which], f, face->gc, 0, p->dh,
- p->wd, p->h, p->x, p->y, p->overlay_p);
+ p->wd, p->h, p->x, p->y, overlay_p);
#else
mac_draw_bitmap (f, face->gc, p->x, p->y,
- p->wd, p->h, p->bits + p->dh, p->overlay_p);
+ p->wd, p->h, p->bits + p->dh, overlay_p);
#endif
XSetForeground (display, face->gc, gcv.foreground);
}
- mac_reset_clip_rectangles (display, face->gc);
+ mac_reset_clip_rectangles (f, face->gc);
}
#if USE_CG_DRAWING
int n;
n = get_glyph_string_clip_rects (s, rects, MAX_CLIP_RECTS);
- mac_set_clip_rectangles (s->display, s->gc, rects, n);
+ mac_set_clip_rectangles (s->f, s->gc, rects, n);
}
Rect r;
MacFontStruct *font = s->font;
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (s->f);
-#endif
- SetPortWindowPort (FRAME_MAC_WINDOW (s->f));
+ mac_begin_clip (s->f, NULL);
TextFont (font->mac_fontnum);
TextSize (font->mac_fontsize);
QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
+ mac_end_clip (s->f, NULL);
+
s->right_overhang = r.right > s->width ? r.right - s->width : 0;
s->left_overhang = r.left < 0 ? -r.left : 0;
}
int top_p, bot_p, left_p, right_p, raised_p;
Rect *clip_rect;
{
- Display *dpy = FRAME_MAC_DISPLAY (f);
int i;
GC gc;
gc = f->output_data.mac->white_relief.gc;
else
gc = f->output_data.mac->black_relief.gc;
- mac_set_clip_rectangles (dpy, gc, clip_rect, 1);
+ mac_set_clip_rectangles (f, gc, clip_rect, 1);
/* Top. */
if (top_p)
mac_draw_line (f, gc,
left_x + i, top_y + i, left_x + i, bottom_y - i + 1);
- mac_reset_clip_rectangles (dpy, gc);
+ mac_reset_clip_rectangles (f, gc);
if (raised_p)
gc = f->output_data.mac->black_relief.gc;
else
gc = f->output_data.mac->white_relief.gc;
- mac_set_clip_rectangles (dpy, gc, clip_rect, 1);
+ mac_set_clip_rectangles (f, gc, clip_rect, 1);
/* Bottom. */
if (bot_p)
mac_draw_line (f, gc,
right_x - i, top_y + i + 1, right_x - i, bottom_y - i);
- mac_reset_clip_rectangles (dpy, gc);
+ mac_reset_clip_rectangles (f, gc);
}
XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
XSetForeground (s->display, s->gc, s->face->box_color);
- mac_set_clip_rectangles (s->display, s->gc, clip_rect, 1);
+ mac_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
/* Top. */
mac_fill_rectangle (s->f, s->gc, left_x, top_y,
top_y, width, bottom_y - top_y + 1);
XSetForeground (s->display, s->gc, xgcv.foreground);
- mac_reset_clip_rectangles (s->display, s->gc);
+ mac_reset_clip_rectangles (s->f, s->gc);
}
gc = s->face->gc;
get_glyph_string_clip_rect (s, &r);
- mac_set_clip_rectangles (s->display, gc, &r, 1);
+ mac_set_clip_rectangles (s->f, gc, &r, 1);
#if 0 /* MAC_TODO: stipple */
if (s->face->stipple)
}
/* Reset clipping. */
- mac_reset_clip_rectangles (s->display, s->gc);
+ mac_reset_clip_rectangles (s->f, s->gc);
}
/* Shift display to make room for inserted glyphs. */
#endif
{
BLOCK_INPUT;
- SysBeep (1);
+ mac_alert_sound_play ();
XFlush (FRAME_MAC_DISPLAY (f));
UNBLOCK_INPUT;
}
frame_highlight (f)
struct frame *f;
{
- OSErr err;
- ControlRef root_control;
-
- BLOCK_INPUT;
- err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control);
- if (err == noErr)
- ActivateControl (root_control);
- UNBLOCK_INPUT;
x_update_cursor (f, 1);
}
frame_unhighlight (f)
struct frame *f;
{
- OSErr err;
- ControlRef root_control;
-
- BLOCK_INPUT;
- err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control);
- if (err == noErr)
- DeactivateControl (root_control);
- UNBLOCK_INPUT;
x_update_cursor (f, 1);
}
If FRAME has focus and there exists more than one frame, puts
a FOCUS_IN_EVENT into *BUFP. */
-static void
+void
mac_focus_changed (type, dpyinfo, frame, bufp)
int type;
struct mac_display_info *dpyinfo;
}
}
-/* The focus may have changed. Figure out if it is a real focus change,
- by checking both FocusIn/Out and Enter/LeaveNotify events.
-
- Returns FOCUS_IN_EVENT event in *BUFP. */
-
-static void
-x_detect_focus_change (dpyinfo, event, bufp)
- struct mac_display_info *dpyinfo;
- const EventRecord *event;
- struct input_event *bufp;
-{
- struct frame *frame;
-
- frame = mac_window_to_frame ((WindowPtr) event->message);
- if (! frame)
- return;
-
- /* On Mac, this is only called from focus events, so no switch needed. */
- mac_focus_changed ((event->modifiers & activeFlag),
- dpyinfo, frame, bufp);
-}
-
-
/* Handle an event saying the mouse has moved out of an Emacs frame. */
void
static Point last_mouse_motion_position;
static Lisp_Object last_mouse_motion_frame;
-static int
+int
note_mouse_movement (frame, pos)
FRAME_PTR frame;
Point *pos;
{
struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (frame);
-#if TARGET_API_MAC_CARBON
Rect r;
-#endif
last_mouse_movement_time = TickCount () * (1000 / 60); /* to milliseconds */
last_mouse_motion_position = *pos;
XSETFRAME (last_mouse_motion_frame, frame);
if (frame == dpyinfo->mouse_face_mouse_frame
-#if TARGET_API_MAC_CARBON
- && !PtInRect (*pos, GetWindowPortBounds (FRAME_MAC_WINDOW (frame), &r))
-#else
- && !PtInRect (*pos, &FRAME_MAC_WINDOW (frame)->portRect)
-#endif
- )
+ && !PtInRect (*pos, mac_get_frame_bounds (frame, &r)))
{
/* This case corresponds to LeaveNotify in X11. If we move
outside the frame, then we're certainly no longer on any text
}
-static struct frame *
+struct frame *
mac_focus_frame (dpyinfo)
struct mac_display_info *dpyinfo;
{
the frame are divided into. */
Point mouse_pos;
- SetPortWindowPort (FRAME_MAC_WINDOW (f1));
- GetMouse (&mouse_pos);
+ mac_get_frame_mouse (f1, &mouse_pos);
remember_mouse_glyph (f1, mouse_pos.h, mouse_pos.v,
&last_mouse_glyph);
last_mouse_glyph_frame = f1;
\f
/************************************************************************
- Toolkit scroll bars
+ Scroll bars, general
************************************************************************/
-#ifdef USE_TOOLKIT_SCROLL_BARS
-
-static pascal void scroll_bar_timer_callback P_ ((EventLoopTimerRef, void *));
-static OSStatus install_scroll_bar_timer P_ ((void));
-static OSStatus set_scroll_bar_timer P_ ((EventTimerInterval));
-static int control_part_code_to_scroll_bar_part P_ ((ControlPartCode));
-static void construct_scroll_bar_click P_ ((struct scroll_bar *, int,
- struct input_event *));
-static OSStatus get_control_part_bounds P_ ((ControlHandle, ControlPartCode,
- Rect *));
-static void x_scroll_bar_handle_press P_ ((struct scroll_bar *,
- ControlPartCode, Point,
- struct input_event *));
-static void x_scroll_bar_handle_release P_ ((struct scroll_bar *,
- struct input_event *));
-static void x_scroll_bar_handle_drag P_ ((WindowPtr, struct scroll_bar *,
- Point, struct input_event *));
-static void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *,
- int, int, int));
-
-/* Last scroll bar part sent in x_scroll_bar_handle_*. */
+/* Create a scroll bar and return the scroll bar vector for it. W is
+ the Emacs window on which to create the scroll bar. TOP, LEFT,
+ WIDTH and HEIGHT are the pixel coordinates and dimensions of the
+ scroll bar. */
-static int last_scroll_bar_part;
+static struct scroll_bar *
+x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
+ struct window *w;
+ int top, left, width, height, disp_top, disp_height;
+{
+ struct frame *f = XFRAME (w->frame);
+ struct scroll_bar *bar
+ = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
+ Rect r;
-static EventLoopTimerRef scroll_bar_timer;
+ BLOCK_INPUT;
-static int scroll_bar_timer_event_posted_p;
+ XSETWINDOW (bar->window, w);
+ XSETINT (bar->top, top);
+ XSETINT (bar->left, left);
+ XSETINT (bar->width, width);
+ XSETINT (bar->height, height);
+#ifdef MAC_OSX
+ bar->fringe_extended_p = Qnil;
+#endif
+ bar->redraw_needed_p = Qnil;
-#define SCROLL_BAR_FIRST_DELAY 0.5
-#define SCROLL_BAR_CONTINUOUS_DELAY (1.0 / 15)
+ SetRect (&r, left, disp_top, left + width, disp_top + disp_height);
+ mac_create_scroll_bar (bar, &r,
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ false
+#else
+ width < disp_height
+#endif
+ );
-static pascal void
-scroll_bar_timer_callback (timer, data)
- EventLoopTimerRef timer;
- void *data;
-{
- OSStatus err;
+ /* Add bar to its frame's list of scroll bars. */
+ bar->next = FRAME_SCROLL_BARS (f);
+ bar->prev = Qnil;
+ XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
+ if (!NILP (bar->next))
+ XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
- err = mac_post_mouse_moved_event ();
- if (err == noErr)
- scroll_bar_timer_event_posted_p = 1;
+ UNBLOCK_INPUT;
+ return bar;
}
-static OSStatus
-install_scroll_bar_timer ()
-{
- static EventLoopTimerUPP scroll_bar_timer_callbackUPP = NULL;
- if (scroll_bar_timer_callbackUPP == NULL)
- scroll_bar_timer_callbackUPP =
- NewEventLoopTimerUPP (scroll_bar_timer_callback);
-
- if (scroll_bar_timer == NULL)
- /* Mac OS X and CarbonLib 1.5 and later allow us to specify
- kEventDurationForever as delays. */
- return
- InstallEventLoopTimer (GetCurrentEventLoop (),
- kEventDurationForever, kEventDurationForever,
- scroll_bar_timer_callbackUPP, NULL,
- &scroll_bar_timer);
-}
+/* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
+ nil. */
-static OSStatus
-set_scroll_bar_timer (delay)
- EventTimerInterval delay;
+static void
+x_scroll_bar_remove (bar)
+ struct scroll_bar *bar;
{
- if (scroll_bar_timer == NULL)
- install_scroll_bar_timer ();
+ BLOCK_INPUT;
+
+ /* Destroy the Mac scroll bar control */
+ mac_dispose_scroll_bar (bar);
- scroll_bar_timer_event_posted_p = 0;
+ /* Disassociate this scroll bar from its window. */
+ XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
- return SetEventLoopTimerNextFireTime (scroll_bar_timer, delay);
-}
-
-static int
-control_part_code_to_scroll_bar_part (part_code)
- ControlPartCode part_code;
-{
- switch (part_code)
- {
- case kControlUpButtonPart: return scroll_bar_up_arrow;
- case kControlDownButtonPart: return scroll_bar_down_arrow;
- case kControlPageUpPart: return scroll_bar_above_handle;
- case kControlPageDownPart: return scroll_bar_below_handle;
- case kControlIndicatorPart: return scroll_bar_handle;
- }
-
- return -1;
-}
-
-static void
-construct_scroll_bar_click (bar, part, bufp)
- struct scroll_bar *bar;
- int part;
- struct input_event *bufp;
-{
- bufp->kind = SCROLL_BAR_CLICK_EVENT;
- bufp->frame_or_window = bar->window;
- bufp->arg = Qnil;
- bufp->part = part;
- bufp->code = 0;
- XSETINT (bufp->x, 0);
- XSETINT (bufp->y, 0);
- bufp->modifiers = 0;
-}
-
-static OSStatus
-get_control_part_bounds (ch, part_code, rect)
- ControlHandle ch;
- ControlPartCode part_code;
- Rect *rect;
-{
- RgnHandle region = NewRgn ();
- OSStatus err;
-
- err = GetControlRegion (ch, part_code, region);
- if (err == noErr)
- GetRegionBounds (region, rect);
- DisposeRgn (region);
-
- return err;
-}
-
-static void
-x_scroll_bar_handle_press (bar, part_code, mouse_pos, bufp)
- struct scroll_bar *bar;
- ControlPartCode part_code;
- Point mouse_pos;
- struct input_event *bufp;
-{
- int part = control_part_code_to_scroll_bar_part (part_code);
-
- if (part < 0)
- return;
-
- if (part != scroll_bar_handle)
- {
- construct_scroll_bar_click (bar, part, bufp);
- HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), part_code);
- set_scroll_bar_timer (SCROLL_BAR_FIRST_DELAY);
- bar->dragging = Qnil;
- }
- else
- {
- Rect r;
-
- get_control_part_bounds (SCROLL_BAR_CONTROL_HANDLE (bar),
- kControlIndicatorPart, &r);
- XSETINT (bar->dragging, - (mouse_pos.v - r.top) - 1);
- }
-
- last_scroll_bar_part = part;
- tracked_scroll_bar = bar;
-}
-
-static void
-x_scroll_bar_handle_release (bar, bufp)
- struct scroll_bar *bar;
- struct input_event *bufp;
-{
- if (last_scroll_bar_part != scroll_bar_handle
- || (INTEGERP (bar->dragging) && XINT (bar->dragging) >= 0))
- construct_scroll_bar_click (bar, scroll_bar_end_scroll, bufp);
-
- HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), 0);
- set_scroll_bar_timer (kEventDurationForever);
-
- last_scroll_bar_part = -1;
- bar->dragging = Qnil;
- tracked_scroll_bar = NULL;
-}
-
-static void
-x_scroll_bar_handle_drag (win, bar, mouse_pos, bufp)
- WindowPtr win;
- struct scroll_bar *bar;
- Point mouse_pos;
- struct input_event *bufp;
-{
- ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
-
- if (last_scroll_bar_part == scroll_bar_handle)
- {
- int top, top_range;
- Rect r;
-
- get_control_part_bounds (SCROLL_BAR_CONTROL_HANDLE (bar),
- kControlIndicatorPart, &r);
-
- if (INTEGERP (bar->dragging) && XINT (bar->dragging) < 0)
- XSETINT (bar->dragging, - (XINT (bar->dragging) + 1));
-
- top = mouse_pos.v - XINT (bar->dragging) - XINT (bar->track_top);
- top_range = XINT (bar->track_height) - XINT (bar->min_handle);
-
- if (top < 0)
- top = 0;
- if (top > top_range)
- top = top_range;
-
- construct_scroll_bar_click (bar, scroll_bar_handle, bufp);
- XSETINT (bufp->x, top);
- XSETINT (bufp->y, top_range);
- }
- else
- {
- ControlPartCode part_code;
- int unhilite_p = 0, part;
-
- if (ch != FindControlUnderMouse (mouse_pos, win, &part_code))
- unhilite_p = 1;
- else
- {
- part = control_part_code_to_scroll_bar_part (part_code);
-
- switch (last_scroll_bar_part)
- {
- case scroll_bar_above_handle:
- case scroll_bar_below_handle:
- if (part != scroll_bar_above_handle
- && part != scroll_bar_below_handle)
- unhilite_p = 1;
- break;
-
- case scroll_bar_up_arrow:
- case scroll_bar_down_arrow:
- if (part != scroll_bar_up_arrow
- && part != scroll_bar_down_arrow)
- unhilite_p = 1;
- break;
- }
- }
-
- if (unhilite_p)
- HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), 0);
- else if (part != last_scroll_bar_part
- || scroll_bar_timer_event_posted_p)
- {
- construct_scroll_bar_click (bar, part, bufp);
- last_scroll_bar_part = part;
- HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), part_code);
- set_scroll_bar_timer (SCROLL_BAR_CONTINUOUS_DELAY);
- }
- }
-}
-
-/* Set the thumb size and position of scroll bar BAR. We are currently
- displaying PORTION out of a whole WHOLE, and our position POSITION. */
-
-static void
-x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
- struct scroll_bar *bar;
- int portion, position, whole;
-{
- ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
- int value, viewsize, maximum;
-
- if (XINT (bar->track_height) == 0)
- return;
-
- if (whole <= portion)
- value = 0, viewsize = 1, maximum = 0;
- else
- {
- float scale;
-
- maximum = XINT (bar->track_height) - XINT (bar->min_handle);
- scale = (float) maximum / (whole - portion);
- value = position * scale + 0.5f;
- viewsize = (int) (portion * scale + 0.5f) + XINT (bar->min_handle);
- }
-
- BLOCK_INPUT;
-
- if (GetControlViewSize (ch) != viewsize
- || GetControl32BitValue (ch) != value
- || GetControl32BitMaximum (ch) != maximum)
- {
- /* Temporarily hide the scroll bar to avoid multiple redraws. */
- SetControlVisibility (ch, false, false);
-
- SetControl32BitMaximum (ch, maximum);
- SetControl32BitValue (ch, value);
- SetControlViewSize (ch, viewsize);
-
- SetControlVisibility (ch, true, true);
- }
-
- UNBLOCK_INPUT;
-}
-
-#endif /* USE_TOOLKIT_SCROLL_BARS */
-
-
-\f
-/************************************************************************
- Scroll bars, general
- ************************************************************************/
-
-/* Create a scroll bar and return the scroll bar vector for it. W is
- the Emacs window on which to create the scroll bar. TOP, LEFT,
- WIDTH and HEIGHT are the pixel coordinates and dimensions of the
- scroll bar. */
-
-static struct scroll_bar *
-x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
- struct window *w;
- int top, left, width, height, disp_top, disp_height;
-{
- struct frame *f = XFRAME (w->frame);
- struct scroll_bar *bar
- = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
- Rect r;
- ControlHandle ch;
-
- BLOCK_INPUT;
-
- r.left = left;
- r.top = disp_top;
- r.right = left + width;
- r.bottom = disp_top + disp_height;
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
-#if TARGET_API_MAC_CARBON
- ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p",
-#ifdef USE_TOOLKIT_SCROLL_BARS
- false,
-#else
- width < disp_height,
-#endif
- 0, 0, 0, kControlScrollBarProc, (long) bar);
-#else
- ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", width < disp_height,
- 0, 0, 0, scrollBarProc, (long) bar);
-#endif
- SET_SCROLL_BAR_CONTROL_HANDLE (bar, ch);
-
- XSETWINDOW (bar->window, w);
- XSETINT (bar->top, top);
- XSETINT (bar->left, left);
- XSETINT (bar->width, width);
- XSETINT (bar->height, height);
- XSETINT (bar->start, 0);
- XSETINT (bar->end, 0);
- bar->dragging = Qnil;
- bar->redraw_needed_p = Qnil;
-#ifdef USE_TOOLKIT_SCROLL_BARS
- bar->track_top = Qnil;
- bar->track_height = Qnil;
- bar->min_handle = Qnil;
-#endif
-
- /* Add bar to its frame's list of scroll bars. */
- bar->next = FRAME_SCROLL_BARS (f);
- bar->prev = Qnil;
- XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
- if (!NILP (bar->next))
- XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
-
- UNBLOCK_INPUT;
- return bar;
-}
-
-
-/* Draw BAR's handle in the proper position.
-
- If the handle is already drawn from START to END, don't bother
- redrawing it, unless REBUILD is non-zero; in that case, always
- redraw it. (REBUILD is handy for drawing the handle after expose
- events.)
-
- Normally, we want to constrain the start and end of the handle to
- fit inside its rectangle, but if the user is dragging the scroll
- bar handle, we want to let them drag it down all the way, so that
- the bar's top is as far down as it goes; otherwise, there's no way
- to move to the very end of the buffer. */
-
-#ifndef USE_TOOLKIT_SCROLL_BARS
-
-static void
-x_scroll_bar_set_handle (bar, start, end, rebuild)
- struct scroll_bar *bar;
- int start, end;
- int rebuild;
-{
- int dragging = ! NILP (bar->dragging);
- ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
- int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
- int length = end - start;
-
- /* If the display is already accurate, do nothing. */
- if (! rebuild
- && start == XINT (bar->start)
- && end == XINT (bar->end))
- return;
-
- BLOCK_INPUT;
-
- /* Make sure the values are reasonable, and try to preserve the
- distance between start and end. */
- if (start < 0)
- start = 0;
- else if (start > top_range)
- start = top_range;
- end = start + length;
-
- if (end < start)
- end = start;
- else if (end > top_range && ! dragging)
- end = top_range;
-
- /* Store the adjusted setting in the scroll bar. */
- XSETINT (bar->start, start);
- XSETINT (bar->end, end);
-
- /* Clip the end position, just for display. */
- if (end > top_range)
- end = top_range;
-
- /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
- top positions, to make sure the handle is always at least that
- many pixels tall. */
- end += VERTICAL_SCROLL_BAR_MIN_HANDLE;
-
- SetControlMinimum (ch, 0);
- /* Don't inadvertently activate deactivated scroll bars */
- if (GetControlMaximum (ch) != -1)
- SetControlMaximum (ch, top_range + VERTICAL_SCROLL_BAR_MIN_HANDLE
- - (end - start));
- SetControlValue (ch, start);
-#if TARGET_API_MAC_CARBON
- SetControlViewSize (ch, end - start);
-#endif
-
- UNBLOCK_INPUT;
-}
-
-#endif /* !USE_TOOLKIT_SCROLL_BARS */
-
-/* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
- nil. */
-
-static void
-x_scroll_bar_remove (bar)
- struct scroll_bar *bar;
-{
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
-
- BLOCK_INPUT;
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- /* Destroy the Mac scroll bar control */
- DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar));
-
- /* Disassociate this scroll bar from its window. */
- XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
-
- UNBLOCK_INPUT;
+ UNBLOCK_INPUT;
}
struct scroll_bar *bar;
int top, height, left, sb_left, width, sb_width, disp_top, disp_height;
int window_y, window_height;
+#ifdef MAC_OSX
+ int fringe_extended_p;
+#endif
/* Get window dimensions. */
window_box (w, -1, 0, &window_y, 0, &window_height);
/* Compute the left edge of the scroll bar. */
if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
- sb_left = left;
+ sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
else
- sb_left = left + width - sb_width;
+ sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
/* Adjustments according to Inside Macintosh to make it look nice */
disp_top = top;
sb_left++;
#endif
+#ifdef MAC_OSX
+ if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+ fringe_extended_p = (WINDOW_LEFTMOST_P (w)
+ && WINDOW_LEFT_FRINGE_WIDTH (w)
+ && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ || WINDOW_LEFT_MARGIN_COLS (w) == 0));
+ else
+ fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
+ && WINDOW_RIGHT_FRINGE_WIDTH (w)
+ && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
+#endif
+
/* Does the scroll bar exist yet? */
if (NILP (w->vertical_scroll_bar))
{
BLOCK_INPUT;
- mac_clear_area (f, left, top, width, height);
+#ifdef MAC_OSX
+ if (fringe_extended_p)
+ mac_clear_area (f, sb_left, top, sb_width, height);
+ else
+#endif
+ mac_clear_area (f, left, top, width, height);
UNBLOCK_INPUT;
bar = x_scroll_bar_create (w, top, sb_left, sb_width, height, disp_top,
disp_height);
else
{
/* It may just need to be moved and resized. */
- ControlHandle ch;
-
bar = XSCROLL_BAR (w->vertical_scroll_bar);
- ch = SCROLL_BAR_CONTROL_HANDLE (bar);
BLOCK_INPUT;
if (XINT (bar->left) == sb_left
&& XINT (bar->top) == top
&& XINT (bar->width) == sb_width
- && XINT (bar->height) == height)
+ && XINT (bar->height) == height
+#ifdef MAC_OSX
+ && !NILP (bar->fringe_extended_p) == fringe_extended_p
+#endif
+ )
{
if (!NILP (bar->redraw_needed_p))
- {
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- Draw1Control (SCROLL_BAR_CONTROL_HANDLE (bar));
- }
+ mac_redraw_scroll_bar (bar);
}
else
{
+ Rect r;
+
/* Since toolkit scroll bars are smaller than the space reserved
for them on the frame, we have to clear "under" them. */
- mac_clear_area (f, left, top, width, height);
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- HideControl (ch);
- MoveControl (ch, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, disp_top);
- SizeControl (ch, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
- disp_height);
-#ifndef USE_TOOLKIT_SCROLL_BARS
- if (sb_width < disp_height)
- ShowControl (ch);
+#ifdef MAC_OSX
+ if (fringe_extended_p)
+ mac_clear_area (f, sb_left, top, sb_width, height);
+ else
#endif
+ mac_clear_area (f, left, top, width, height);
+
+ SetRect (&r, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, disp_top,
+ sb_left + sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM,
+ disp_top + disp_height);
+ mac_set_scroll_bar_bounds (bar, &r);
/* Remember new settings. */
XSETINT (bar->left, sb_left);
XSETINT (bar->top, top);
XSETINT (bar->width, sb_width);
XSETINT (bar->height, height);
-#ifdef USE_TOOLKIT_SCROLL_BARS
- bar->track_top = Qnil;
- bar->track_height = Qnil;
- bar->min_handle = Qnil;
-#endif
}
UNBLOCK_INPUT;
}
- bar->redraw_needed_p = Qnil;
-
-#ifdef USE_TOOLKIT_SCROLL_BARS
- if (NILP (bar->track_top))
- {
- if (sb_width >= disp_height
#ifdef MAC_OSX
- || sb_width < MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH
+ bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
#endif
- )
- {
- XSETINT (bar->track_top, 0);
- XSETINT (bar->track_height, 0);
- XSETINT (bar->min_handle, 0);
- }
- else
- {
- ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
- Rect r0, r1;
-
- BLOCK_INPUT;
-
- SetControl32BitMinimum (ch, 0);
- SetControl32BitMaximum (ch, 1 << 30);
- SetControlViewSize (ch, 1);
-
- /* Move the scroll bar thumb to the top. */
- SetControl32BitValue (ch, 0);
- get_control_part_bounds (ch, kControlIndicatorPart, &r0);
-
- /* Move the scroll bar thumb to the bottom. */
- SetControl32BitValue (ch, 1 << 30);
- get_control_part_bounds (ch, kControlIndicatorPart, &r1);
-
- UnionRect (&r0, &r1, &r0);
- XSETINT (bar->track_top, r0.top);
- XSETINT (bar->track_height, r0.bottom - r0.top);
- XSETINT (bar->min_handle, r1.bottom - r1.top);
-
- /* Don't show the scroll bar if its height is not enough to
- display the scroll bar thumb. */
- if (r0.bottom - r0.top > 0)
- ShowControl (ch);
-
- UNBLOCK_INPUT;
- }
- }
+ bar->redraw_needed_p = Qnil;
+#ifdef USE_TOOLKIT_SCROLL_BARS
x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
#else /* not USE_TOOLKIT_SCROLL_BARS */
/* Set the scroll bar's current state, unless we're currently being
and they should get garbage-collected. */
}
+/* The screen has been cleared so we may have changed foreground or
+ background colors, and the scroll bars may need to be redrawn.
+ Clear out the scroll bars, and ask for expose events, so we can
+ redraw them. */
-/* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
- is set to something other than NO_EVENT, it is enqueued.
-
- This may be called from a signal handler, so we have to ignore GC
- mark bits. */
-
-static void
-x_scroll_bar_handle_click (bar, part_code, er, bufp)
- struct scroll_bar *bar;
- ControlPartCode part_code;
- const EventRecord *er;
- struct input_event *bufp;
+void
+x_scroll_bar_clear (f)
+ FRAME_PTR f;
{
- int win_y, top_range;
+ Lisp_Object bar;
- if (! GC_WINDOWP (bar->window))
- abort ();
+ /* We can have scroll bars even if this is 0,
+ if we just turned off scroll bar mode.
+ But in that case we should not clear them. */
+ if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+ for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
+ bar = XSCROLL_BAR (bar)->next)
+ XSCROLL_BAR (bar)->redraw_needed_p = Qt;
+}
- bufp->kind = SCROLL_BAR_CLICK_EVENT;
- bufp->frame_or_window = bar->window;
- bufp->arg = Qnil;
+\f
+/***********************************************************************
+ Tool-bars
+ ***********************************************************************/
+#if USE_MAC_TOOLBAR
+void
+mac_move_window_with_gravity (f, win_gravity, left, top)
+ struct frame *f;
+ int win_gravity;
+ short left, top;
+{
+ Rect inner, outer;
- bar->dragging = Qnil;
+ mac_get_window_bounds (f, &inner, &outer);
- switch (part_code)
+ switch (win_gravity)
{
- case kControlUpButtonPart:
- bufp->part = scroll_bar_up_arrow;
+ case NorthWestGravity:
+ case WestGravity:
+ case SouthWestGravity:
+ left += inner.left - outer.left;
break;
- case kControlDownButtonPart:
- bufp->part = scroll_bar_down_arrow;
- break;
- case kControlPageUpPart:
- bufp->part = scroll_bar_above_handle;
- break;
- case kControlPageDownPart:
- bufp->part = scroll_bar_below_handle;
+
+ case NorthGravity:
+ case CenterGravity:
+ case SouthGravity:
+ left += ((inner.left - outer.left) + (inner.right - outer.right)) / 2;
break;
-#if TARGET_API_MAC_CARBON
- default:
-#else
- case kControlIndicatorPart:
-#endif
- if (er->what == mouseDown)
- bar->dragging = make_number (0);
- XSETVECTOR (last_mouse_scroll_bar, bar);
- bufp->part = scroll_bar_handle;
+
+ case NorthEastGravity:
+ case EastGravity:
+ case SouthEastGravity:
+ left += inner.right - outer.right;
break;
}
- win_y = XINT (bufp->y) - XINT (bar->top);
- top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar->height));
-
- win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
-
- win_y -= 24;
+ switch (win_gravity)
+ {
+ case NorthWestGravity:
+ case NorthGravity:
+ case NorthEastGravity:
+ top += inner.top - outer.top;
+ break;
- if (! NILP (bar->dragging))
- win_y -= XINT (bar->dragging);
+ case WestGravity:
+ case CenterGravity:
+ case EastGravity:
+ top += ((inner.top - outer.top) + (inner.bottom - outer.bottom)) / 2;
+ break;
- if (win_y < 0)
- win_y = 0;
- if (win_y > top_range)
- win_y = top_range;
+ case SouthWestGravity:
+ case SouthGravity:
+ case SouthEastGravity:
+ top += inner.bottom - outer.bottom;
+ break;
+ }
- XSETINT (bufp->x, win_y);
- XSETINT (bufp->y, top_range);
+ mac_move_window (FRAME_MAC_WINDOW (f), left, top, false);
}
-#ifndef USE_TOOLKIT_SCROLL_BARS
-
-/* Handle some mouse motion while someone is dragging the scroll bar.
+void
+mac_get_window_origin_with_gravity (f, win_gravity, left, top)
+ struct frame *f;
+ int win_gravity;
+ short *left, *top;
+{
+ Rect inner, outer;
- This may be called from a signal handler, so we have to ignore GC
- mark bits. */
+ mac_get_window_bounds (f, &inner, &outer);
-static void
-x_scroll_bar_note_movement (bar, y_pos, t)
- struct scroll_bar *bar;
- int y_pos;
- Time t;
-{
- FRAME_PTR f = XFRAME (XWINDOW (bar->window)->frame);
+ switch (win_gravity)
+ {
+ case NorthWestGravity:
+ case WestGravity:
+ case SouthWestGravity:
+ *left = outer.left;
+ break;
- last_mouse_movement_time = t;
+ case NorthGravity:
+ case CenterGravity:
+ case SouthGravity:
+ *left = outer.left + ((outer.right - outer.left)
+ - (inner.right - inner.left)) / 2;
+ break;
- f->mouse_moved = 1;
- XSETVECTOR (last_mouse_scroll_bar, bar);
+ case NorthEastGravity:
+ case EastGravity:
+ case SouthEastGravity:
+ *left = outer.right - (inner.right - inner.left);
+ break;
+ }
- /* If we're dragging the bar, display it. */
- if (! GC_NILP (bar->dragging))
+ switch (win_gravity)
{
- /* Where should the handle be now? */
- int new_start = y_pos - 24;
+ case NorthWestGravity:
+ case NorthGravity:
+ case NorthEastGravity:
+ *top = outer.top;
+ break;
- if (new_start != XINT (bar->start))
- {
- int new_end = new_start + (XINT (bar->end) - XINT (bar->start));
+ case WestGravity:
+ case CenterGravity:
+ case EastGravity:
+ *top = outer.top + ((outer.bottom - outer.top)
+ - (inner.bottom - inner.top)) / 2;
+ break;
- x_scroll_bar_set_handle (bar, new_start, new_end, 0);
- }
+ case SouthWestGravity:
+ case SouthGravity:
+ case SouthEastGravity:
+ *top = outer.bottom - (inner.bottom - inner.top);
+ break;
}
}
-#endif /* !USE_TOOLKIT_SCROLL_BARS */
-
-/* Return information to the user about the current position of the mouse
- on the scroll bar. */
-
-static void
-x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
- FRAME_PTR *fp;
- Lisp_Object *bar_window;
- enum scroll_bar_part *part;
- Lisp_Object *x, *y;
- unsigned long *time;
+CGImageRef
+mac_image_spec_to_cg_image (f, image)
+ struct frame *f;
+ Lisp_Object image;
{
- struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
- ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
-#if TARGET_API_MAC_CARBON
- WindowPtr wp = GetControlOwner (ch);
-#else
- WindowPtr wp = (*ch)->contrlOwner;
-#endif
- Point mouse_pos;
- struct frame *f = mac_window_to_frame (wp);
- int win_y, top_range;
-
- SetPortWindowPort (wp);
-
- GetMouse (&mouse_pos);
-
- win_y = mouse_pos.v - XINT (bar->top);
- top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
-
- win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
-
- win_y -= 24;
-
- if (! NILP (bar->dragging))
- win_y -= XINT (bar->dragging);
-
- if (win_y < 0)
- win_y = 0;
- if (win_y > top_range)
- win_y = top_range;
-
- *fp = f;
- *bar_window = bar->window;
-
- if (! NILP (bar->dragging))
- *part = scroll_bar_handle;
- else if (win_y < XINT (bar->start))
- *part = scroll_bar_above_handle;
- else if (win_y < XINT (bar->end) + VERTICAL_SCROLL_BAR_MIN_HANDLE)
- *part = scroll_bar_handle;
+ if (!valid_image_p (image))
+ return NULL;
else
- *part = scroll_bar_below_handle;
-
- XSETINT (*x, win_y);
- XSETINT (*y, top_range);
-
- f->mouse_moved = 0;
- last_mouse_scroll_bar = Qnil;
-
- *time = last_mouse_movement_time;
-}
-
-
-/* The screen has been cleared so we may have changed foreground or
- background colors, and the scroll bars may need to be redrawn.
- Clear out the scroll bars, and ask for expose events, so we can
- redraw them. */
+ {
+ int img_id = lookup_image (f, image);
+ struct image *img = IMAGE_FROM_ID (f, img_id);
-void
-x_scroll_bar_clear (f)
- FRAME_PTR f;
-{
- Lisp_Object bar;
+ prepare_image_for_display (f, img);
- /* We can have scroll bars even if this is 0,
- if we just turned off scroll bar mode.
- But in that case we should not clear them. */
- if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
- for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
- bar = XSCROLL_BAR (bar)->next)
- XSCROLL_BAR (bar)->redraw_needed_p = Qt;
+ return img->data.ptr_val;
+ }
}
+#endif /* USE_MAC_TOOLBAR */
\f
/***********************************************************************
clip_rect.right = clip_rect.left + window_width;
clip_rect.bottom = clip_rect.top + row->visible_height;
- mac_set_clip_rectangles (FRAME_MAC_DISPLAY (f), gc, &clip_rect, 1);
+ mac_set_clip_rectangles (f, gc, &clip_rect, 1);
}
/* Set clipping, draw the rectangle, and reset clipping again. */
x_clip_to_row (w, row, TEXT_AREA, gc);
mac_draw_rectangle (f, gc, x, y, wd, h - 1);
- mac_reset_clip_rectangles (dpy, gc);
+ mac_reset_clip_rectangles (f, gc);
}
cursor_glyph->pixel_width,
width);
- mac_reset_clip_rectangles (dpy, gc);
+ mac_reset_clip_rectangles (f, gc);
}
}
\f
void
-mac_get_window_bounds (f, inner, outer)
- struct frame *f;
- Rect *inner, *outer;
-{
-#if TARGET_API_MAC_CARBON
- GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowContentRgn, inner);
- GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowStructureRgn, outer);
-#else /* not TARGET_API_MAC_CARBON */
- RgnHandle region = NewRgn ();
-
- GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowContentRgn, region);
- *inner = (*region)->rgnBBox;
- GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowStructureRgn, region);
- *outer = (*region)->rgnBBox;
- DisposeRgn (region);
-#endif /* not TARGET_API_MAC_CARBON */
-}
-
-static void
mac_handle_origin_change (f)
struct frame *f;
{
x_real_positions (f, &f->left_pos, &f->top_pos);
}
-static void
+void
mac_handle_size_change (f, pixelwidth, pixelheight)
struct frame *f;
int pixelwidth, pixelheight;
change_frame_size (f, rows, cols, 0, 1, 0);
FRAME_PIXEL_WIDTH (f) = pixelwidth;
FRAME_PIXEL_HEIGHT (f) = pixelheight;
- SET_FRAME_GARBAGED (f);
/* If cursor was outside the new size, mark it as off. */
mark_window_cursors_off (XWINDOW (f->root_window));
cancel_mouse_face (f);
#if TARGET_API_MAC_CARBON
- if (f->output_data.mac->hourglass_control)
- {
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- MoveControl (f->output_data.mac->hourglass_control,
- pixelwidth - HOURGLASS_WIDTH, 0);
- }
+ mac_reposition_hourglass (f);
#endif
}
}
x_calc_absolute_position (f)
struct frame *f;
{
- int width_diff = 0, height_diff = 0;
int flags = f->size_hint_flags;
Rect inner, outer;
mac_get_window_bounds (f, &inner, &outer);
UNBLOCK_INPUT;
- width_diff = (outer.right - outer.left) - (inner.right - inner.left);
- height_diff = (outer.bottom - outer.top) - (inner.bottom - inner.top);
-
/* Treat negative positions as relative to the leftmost bottommost
position that fits on the screen. */
if (flags & XNegative)
- f->left_pos = (FRAME_MAC_DISPLAY_INFO (f)->width
- - width_diff
- - FRAME_PIXEL_WIDTH (f)
- + f->left_pos);
+ f->left_pos += (FRAME_MAC_DISPLAY_INFO (f)->width
+ - (outer.right - outer.left));
if (flags & YNegative)
- f->top_pos = (FRAME_MAC_DISPLAY_INFO (f)->height
- - height_diff
- - FRAME_PIXEL_HEIGHT (f)
- + f->top_pos);
+ f->top_pos += (FRAME_MAC_DISPLAY_INFO (f)->height
+ - (outer.bottom - outer.top));
/* The left_pos and top_pos
are now relative to the top and left screen edges,
x_wm_set_size_hint (f, (long) 0, 0);
#if TARGET_API_MAC_CARBON
- MoveWindowStructure (FRAME_MAC_WINDOW (f), f->left_pos, f->top_pos);
+ mac_move_window_structure (FRAME_MAC_WINDOW (f), f->left_pos, f->top_pos);
/* If the title bar is completely outside the screen, adjust the
position. */
ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
kWindowConstrainMoveRegardlessOfFit
| kWindowConstrainAllowPartial, NULL, NULL);
-#if USE_CARBON_EVENTS
if (!NILP (tip_frame) && XFRAME (tip_frame) == f)
-#endif
mac_handle_origin_change (f);
#else
{
f->win_gravity = NorthWestGravity;
x_wm_set_size_hint (f, (long) 0, 0);
- SizeWindow (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0);
+ mac_size_window (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0);
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
if (!NILP (tip_frame) && f == XFRAME (tip_frame))
#endif
mac_handle_size_change (f, pixelwidth, pixelheight);
int pix_x, pix_y;
{
#ifdef MAC_OSX
- Point p;
- CGPoint point;
-
BLOCK_INPUT;
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
- p.h = pix_x;
- p.v = pix_y;
- LocalToGlobal (&p);
- point.x = p.h;
- point.y = p.v;
- CGWarpMouseCursorPosition (point);
+ mac_convert_frame_point_to_global (f, &pix_x, &pix_y);
+ CGWarpMouseCursorPosition (CGPointMake (pix_x, pix_y));
UNBLOCK_INPUT;
#else
#if 0 /* MAC_TODO: LMSetMouseLocation and CursorDeviceMoveTo are non-Carbon */
if (f->async_visible)
{
BLOCK_INPUT;
- BringToFront (FRAME_MAC_WINDOW (f));
+ mac_bring_window_to_front (FRAME_MAC_WINDOW (f));
UNBLOCK_INPUT;
}
}
if (f->async_visible)
{
BLOCK_INPUT;
- SendBehind (FRAME_MAC_WINDOW (f), NULL);
+ mac_send_window_behind (FRAME_MAC_WINDOW (f), NULL);
UNBLOCK_INPUT;
}
}
\f
/* Change of visibility. */
-static void
+void
mac_handle_visibility_change (f)
struct frame *f;
{
- WindowPtr wp = FRAME_MAC_WINDOW (f);
+ Window wp = FRAME_MAC_WINDOW (f);
int visible = 0, iconified = 0;
struct input_event buf;
- if (IsWindowVisible (wp))
+ if (mac_is_window_visible (wp))
{
- if (IsWindowCollapsed (wp))
+ if (mac_is_window_collapsed (wp))
iconified = 1;
else
visible = 1;
before the window gets really visible. */
if (! FRAME_ICONIFIED_P (f)
&& ! f->output_data.mac->asked_for_visible)
- {
-#if TARGET_API_MAC_CARBON
- if (!(FRAME_SIZE_HINTS (f)->flags & (USPosition | PPosition)))
- {
- struct frame *sf = SELECTED_FRAME ();
- if (!FRAME_MAC_P (sf))
- RepositionWindow (FRAME_MAC_WINDOW (f), NULL,
- kWindowCenterOnMainScreen);
- else
- RepositionWindow (FRAME_MAC_WINDOW (f),
- FRAME_MAC_WINDOW (sf),
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- kWindowCascadeStartAtParentWindowScreen
-#else
- kWindowCascadeOnParentWindowScreen
-#endif
- );
-#if USE_CARBON_EVENTS
- if (!NILP (tip_frame) && f == XFRAME (tip_frame))
-#endif
- mac_handle_origin_change (f);
- }
- else
-#endif
- x_set_offset (f, f->left_pos, f->top_pos, 0);
- }
+ x_set_offset (f, f->left_pos, f->top_pos, 0);
f->output_data.mac->asked_for_visible = 1;
- CollapseWindow (FRAME_MAC_WINDOW (f), false);
- ShowWindow (FRAME_MAC_WINDOW (f));
+ mac_collapse_window (FRAME_MAC_WINDOW (f), false);
+ mac_show_window (FRAME_MAC_WINDOW (f));
}
XFlush (FRAME_MAC_DISPLAY (f));
BLOCK_INPUT;
+#if !TARGET_API_MAC_CARBON
/* Before unmapping the window, update the WM_SIZE_HINTS property to claim
that the current position of the window is user-specified, rather than
program-specified, so that when the window is mapped again, it will be
placed at the same location, without forcing the user to position it
by hand again (they have already done that once for this window.) */
x_wm_set_size_hint (f, (long) 0, 1);
+#endif
- HideWindow (FRAME_MAC_WINDOW (f));
+ mac_hide_window (FRAME_MAC_WINDOW (f));
UNBLOCK_INPUT;
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
mac_handle_visibility_change (f);
#endif
}
FRAME_SAMPLE_VISIBILITY (f);
if (! FRAME_VISIBLE_P (f))
- ShowWindow (FRAME_MAC_WINDOW (f));
+ mac_show_window (FRAME_MAC_WINDOW (f));
- err = CollapseWindow (FRAME_MAC_WINDOW (f), true);
+ err = mac_collapse_window (FRAME_MAC_WINDOW (f), true);
UNBLOCK_INPUT;
if (err != noErr)
error ("Can't notify window manager of iconification");
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
mac_handle_visibility_change (f);
#endif
}
struct frame *f;
{
struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- WindowPtr wp = FRAME_MAC_WINDOW (f);
+ Window wp = FRAME_MAC_WINDOW (f);
BLOCK_INPUT;
- if (wp != tip_window)
- remove_window_handler (wp);
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- DisposeWindow (wp);
- if (wp == tip_window)
- /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
- closed' event. So we reset tip_window here. */
- tip_window = NULL;
-
- free_frame_menubar (f);
-
- if (FRAME_FACE_CACHE (f))
- free_frame_faces (f);
-
- x_free_gcs (f);
-
- if (FRAME_SIZE_HINTS (f))
- xfree (FRAME_SIZE_HINTS (f));
-
- xfree (f->output_data.mac);
- f->output_data.mac = NULL;
-
+ /* AppKit version of mac_dispose_frame_window, which is implemented
+ as -[NSWindow close], will change the focus to the next window
+ during its call. So, unlike other platforms, we clean up the
+ focus-related variables before calling mac_dispose_frame_window. */
if (f == dpyinfo->x_focus_frame)
{
dpyinfo->x_focus_frame = 0;
dpyinfo->mouse_face_mouse_frame = 0;
}
+ mac_dispose_frame_window (f);
+ if (wp == tip_window)
+ /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
+ closed' event. So we reset tip_window here. */
+ tip_window = NULL;
+
+ free_frame_menubar (f);
+
+ if (FRAME_FACE_CACHE (f))
+ free_frame_faces (f);
+
+ x_free_gcs (f);
+
+ if (FRAME_SIZE_HINTS (f))
+ xfree (FRAME_SIZE_HINTS (f));
+
+ xfree (f->output_data.mac);
+ f->output_data.mac = NULL;
+
UNBLOCK_INPUT;
}
static Lisp_Object fm_style_face_attributes_alist;
extern Lisp_Object QCfamily, QCweight, QCslant, Qnormal, Qbold, Qitalic;
#endif
+#if USE_MAC_FONT_PANEL
+Lisp_Object Qpanel_closed, Qselection;
+#endif
/* Alist linking character set strings to Mac text encoding and Emacs
coding system. */
FontInfo the_fontinfo;
int is_two_byte_font;
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
+ mac_begin_clip (f, NULL);
TextFont (fontnum);
TextSize (size);
for (c = 0x21, pcm = space_bounds + 1; c <= 0xff; c++, pcm++)
mac_query_char_extents (NULL, c, NULL, NULL, pcm, NULL);
}
+
+ mac_end_clip (f, NULL);
}
if (space_bounds)
for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
if ((pcm = mac_per_char_metric (font, &char2b, 0)) != NULL)
width += pcm->width;
- fontp->average_width = width / 95;
+ fontp->average_width = width / 95.0 + 0.5;
}
else
fontp->average_width = FONT_WIDTH (font);
}
}
-#if USE_MAC_FONT_PANEL
-/* Whether Font Panel has been shown before. The first call to font
- panel functions (FPIsFontPanelVisible, SetFontInfoForSelection) is
- slow. This variable is used for deferring such a call as much as
- possible. */
-static int font_panel_shown_p = 0;
-
-int
-mac_font_panel_visible_p ()
-{
- return font_panel_shown_p && FPIsFontPanelVisible ();
-}
-
-OSStatus
-mac_show_hide_font_panel ()
-{
- font_panel_shown_p = 1;
-
- return FPShowHideFontPanel ();
-}
-
-OSStatus
-mac_set_font_info_for_selection (f, face_id, c)
- struct frame *f;
- int face_id, c;
-{
- OSStatus err;
- EventTargetRef target = NULL;
- XFontStruct *font = NULL;
-
- if (!mac_font_panel_visible_p ())
- return noErr;
-
- if (f)
- {
- target = GetWindowEventTarget (FRAME_MAC_WINDOW (f));
-
- if (FRAME_FACE_CACHE (f) && CHAR_VALID_P (c, 0))
- {
- struct face *face;
-
- face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
- face = FACE_FROM_ID (f, face_id);
- font = face->font;
- }
- }
-
- if (font == NULL)
- err = SetFontInfoForSelection (kFontSelectionATSUIType, 0, NULL, target);
- else
- {
- if (font->mac_fontnum != -1)
- {
- FontSelectionQDStyle qd_style;
-
- qd_style.version = kFontSelectionQDStyleVersionZero;
- qd_style.instance.fontFamily = font->mac_fontnum;
- qd_style.instance.fontStyle = font->mac_fontface;
- qd_style.size = font->mac_fontsize;
- qd_style.hasColor = false;
-
- err = SetFontInfoForSelection (kFontSelectionQDType,
- 1, &qd_style, target);
- }
- else
- err = SetFontInfoForSelection (kFontSelectionATSUIType,
- 1, &font->mac_style, target);
- }
-
- return err;
-}
-#endif
-
\f
/* The Mac Event loop code */
#endif
#endif /* ! TARGET_API_MAC_CARBON */
-#define M_APPLE 234
-#define I_ABOUT 1
-
-#define DEFAULT_NUM_COLS 80
-
-#define MIN_DOC_SIZE 64
-#define MAX_DOC_SIZE 32767
-
-#define EXTRA_STACK_ALLOC (256 * 1024)
-
-#define ARGV_STRING_LIST_ID 129
-#define ABOUT_ALERT_ID 128
-#define RAM_TOO_LARGE_ALERT_ID 129
-
/* Contains the string "reverse", which is a constant for mouse button emu.*/
Lisp_Object Qreverse;
a three button mouse */
Lisp_Object Vmac_emulate_three_button_mouse;
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
/* Non-zero if the mouse wheel button (i.e. button 4) should map to
mouse-2, instead of mouse-3. */
int mac_wheel_button_is_mouse_2;
int mac_pass_control_to_system;
#endif
-/* Points to the variable `inev' in the function XTread_socket. It is
- used for passing an input event to the function back from
- Carbon/Apple event handlers. */
-static struct input_event *read_socket_inev = NULL;
-
/* Whether or not the screen configuration has changed. */
-static int mac_screen_config_changed = 0;
-
-Point saved_menu_event_location;
+int mac_screen_config_changed = 0;
/* Apple Events */
-#if USE_CARBON_EVENTS
-static Lisp_Object Qhi_command;
+#if TARGET_API_MAC_CARBON
+Lisp_Object Qhi_command;
#ifdef MAC_OSX
-extern Lisp_Object Qwindow;
-static Lisp_Object Qtoolbar_switch_mode;
-#endif
-#if USE_MAC_FONT_PANEL
-extern Lisp_Object Qfont;
-static Lisp_Object Qpanel_closed, Qselection;
+Lisp_Object Qtoolbar_switch_mode;
#endif
#if USE_MAC_TSM
-static TSMDocumentID tsm_document_id;
-static Lisp_Object Qtext_input;
-static Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
-static Lisp_Object Vmac_ts_active_input_overlay;
-extern Lisp_Object Qbefore_string;
+Lisp_Object Qtext_input;
+Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
+Lisp_Object Vmac_ts_active_input_overlay, Vmac_ts_active_input_buf;
static Lisp_Object Vmac_ts_script_language_on_focus;
static Lisp_Object saved_ts_script_language_on_focus;
static ScriptLanguageRecord saved_ts_language;
static Component saved_ts_component;
#endif
+#ifdef MAC_OSX
+Lisp_Object Qservice, Qpaste, Qperform;
+Lisp_Object Qmouse_drag_overlay;
#endif
-extern int mac_ready_for_apple_events;
+#endif /* TARGET_API_MAC_CARBON */
extern Lisp_Object Qundefined;
+extern int XTread_socket P_ ((int, int, struct input_event *));
extern void init_apple_event_handler P_ ((void));
extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID,
Lisp_Object *, Lisp_Object *,
Lisp_Object *));
extern OSErr init_coercion_handler P_ ((void));
-/* Drag and Drop */
-extern OSErr install_drag_handler P_ ((WindowRef));
-extern void remove_drag_handler P_ ((WindowRef));
-
-/* Showing help echo string during menu tracking */
-extern OSStatus install_menu_target_item_handler P_ ((WindowPtr));
-
-#if USE_CARBON_EVENTS
-#ifdef MAC_OSX
-extern void init_service_handler ();
-static Lisp_Object Qservice, Qpaste, Qperform;
-#endif
-
-/* Window Event Handler */
-static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
- EventRef, void *);
-#endif
-OSStatus install_window_handler (WindowPtr);
-
-extern void init_emacs_passwd_dir ();
-extern int emacs_main (int, char **, char **);
-
-extern void initialize_applescript();
-extern void terminate_applescript();
-
/* Table for translating Mac keycode to X keysym values. Contributed
by Sudhir Shenoy.
Mapping for special keys is now identical to that in Apple X11
except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>)
on the right of the Cmd key on laptops, and fn + `enter' (->
<linefeed>). */
-static const unsigned char keycode_to_xkeysym_table[] = {
+const unsigned char keycode_to_xkeysym_table[] = {
/*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*0x38*/ 0, 0, 0, 0,
/*0x3C*/ 0, 0, 0, 0,
- /*0x40*/ 0, 0xae /*kp-decimal*/, 0, 0xaa /*kp-multiply*/,
+ /*0x40*/ 0xce /*f17*/, 0xae /*kp-decimal*/, 0, 0xaa /*kp-multiply*/,
/*0x44*/ 0, 0xab /*kp-add*/, 0, 0x0b /*clear*/,
/*0x48*/ 0, 0, 0, 0xaf /*kp-divide*/,
- /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp-subtract*/, 0,
+ /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp-subtract*/, 0xcf /*f18*/,
- /*0x50*/ 0, 0xbd /*kp-equal*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
+ /*0x50*/ 0xd0 /*f19*/, 0xbd /*kp-equal*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
/*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
/*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
/*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
/*0x38*/ 0, 0, 0, 0,
/*0x3C*/ 0, 0, 0, 0,
- /*0x40*/ 0, 0x2f /*kp-decimal -> '.'*/, 0, 0x23 /*kp-multiply -> 'p'*/,
+ /*0x40*/ 0x40 /*f17 = f17*/, 0x2f /*kp-decimal -> '.'*/, 0, 0x23 /*kp-multiply -> 'p'*/,
/*0x44*/ 0, 0x2c /*kp-add -> '/'*/, 0, 0x16 /*clear -> '6'*/,
/*0x48*/ 0, 0, 0, 0x1d /*kp-/ -> '0'*/,
- /*0x4C*/ 0x24 /*kp-enter -> return*/, 0, 0x29 /*kp-subtract -> ';'*/, 0,
+ /*0x4C*/ 0x24 /*kp-enter -> return*/, 0, 0x29 /*kp-subtract -> ';'*/, 0x4f /*f18 = f18*/,
- /*0x50*/ 0, 0x1b /*kp-equal -> '-'*/, 0x2e /*kp-0 -> 'm'*/, 0x26 /*kp-1 -> 'j'*/,
+ /*0x50*/ 0x50 /*f19 = f19*/, 0x1b /*kp-equal -> '-'*/, 0x2e /*kp-0 -> 'm'*/, 0x26 /*kp-1 -> 'j'*/,
/*0x54*/ 0x28 /*kp-2 -> 'k'*/, 0x25 /*kp-3 -> 'l'*/, 0x20 /*kp-4 -> 'u'*/, 0x22 /*kp-5 ->'i'*/,
/*0x58*/ 0x1f /*kp-6 -> 'o'*/, 0x1a /*kp-7 -> '7'*/, 0, 0x1c /*kp-8 -> '8'*/,
/*0x5C*/ 0x19 /*kp-9 -> '9'*/, 0, 0, 0,
};
#endif /* MAC_OSX */
-static int
-#if USE_CARBON_EVENTS
+int
+#if TARGET_API_MAC_CARBON
mac_to_emacs_modifiers (UInt32 mods, UInt32 unmapped_mods)
#else
mac_to_emacs_modifiers (EventModifiers mods, EventModifiers unmapped_mods)
return result;
}
-static UInt32
+UInt32
mac_mapped_modifiers (modifiers, key_code)
UInt32 modifiers, key_code;
{
return mapped_modifiers_all & modifiers;
}
-static int
+int
mac_get_emulated_btn ( UInt32 modifiers )
{
int result = 0;
return result;
}
-#if TARGET_API_MAC_CARBON
-/***** Code to handle C-g testing *****/
-extern int quit_char;
-extern int make_ctrl_char P_ ((int));
+#ifdef MAC_OSX
+void
+mac_get_selected_range (w, range)
+ struct window *w;
+ CFRange *range;
+{
+ Lisp_Object overlay = find_symbol_value (Qmouse_drag_overlay);
+ struct buffer *b = XBUFFER (w->buffer);
+ int begv = BUF_BEGV (b), zv = BUF_ZV (b);
+ int start, end;
+
+ if (OVERLAYP (overlay)
+ && EQ (Foverlay_buffer (overlay), w->buffer)
+ && (start = XINT (Foverlay_start (overlay)),
+ end = XINT (Foverlay_end (overlay)),
+ start != end))
+ ;
+ else
+ {
+ if (w == XWINDOW (selected_window) && b == current_buffer)
+ start = PT;
+ else
+ start = marker_position (w->pointm);
-int
-mac_quit_char_key_p (modifiers, key_code)
- UInt32 modifiers, key_code;
-{
- UInt32 char_code, mapped_modifiers;
- unsigned long some_state = 0;
- Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
- int c, emacs_modifiers;
-
- /* Mask off modifier keys that are mapped to some Emacs modifiers. */
- mapped_modifiers = mac_mapped_modifiers (modifiers, key_code);
- key_code |= (modifiers & ~mapped_modifiers);
- char_code = KeyTranslate (kchr_ptr, key_code, &some_state);
- if (char_code & ~0xff)
- return 0;
-
- emacs_modifiers = mac_to_emacs_modifiers (mapped_modifiers, modifiers);
- if (emacs_modifiers & ctrl_modifier)
- c = make_ctrl_char (char_code);
-
- c |= (emacs_modifiers
- & (meta_modifier | alt_modifier
- | hyper_modifier | super_modifier));
-
- return c == quit_char;
-}
-#endif
-
-#if USE_CARBON_EVENTS
-/* Obtains the event modifiers from the event ref and then calls
- mac_to_emacs_modifiers. */
-static int
-mac_event_to_emacs_modifiers (EventRef eventRef)
-{
- UInt32 mods = 0;
- GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
- sizeof (UInt32), NULL, &mods);
- if (!NILP (Vmac_emulate_three_button_mouse) &&
- GetEventClass(eventRef) == kEventClassMouse)
- {
- mods &= ~(optionKey | cmdKey);
- }
- return mac_to_emacs_modifiers (mods, 0);
-}
-
-/* Given an event ref, return the code to use for the mouse button
- code in the emacs input_event. */
-static int
-mac_get_mouse_btn (EventRef ref)
-{
- EventMouseButton result = kEventMouseButtonPrimary;
- GetEventParameter (ref, kEventParamMouseButton, typeMouseButton, NULL,
- sizeof (EventMouseButton), NULL, &result);
- switch (result)
- {
- case kEventMouseButtonPrimary:
- if (NILP (Vmac_emulate_three_button_mouse))
- return 0;
- else {
- UInt32 mods = 0;
- GetEventParameter (ref, kEventParamKeyModifiers, typeUInt32, NULL,
- sizeof (UInt32), NULL, &mods);
- return mac_get_emulated_btn(mods);
- }
- case kEventMouseButtonSecondary:
- return mac_wheel_button_is_mouse_2 ? 2 : 1;
- case kEventMouseButtonTertiary:
- case 4: /* 4 is the number for the mouse wheel button */
- return mac_wheel_button_is_mouse_2 ? 1 : 2;
- default:
- return 0;
- }
-}
-
-/* Normally, ConvertEventRefToEventRecord will correctly handle all
- events. However the click of the mouse wheel is not converted to a
- mouseDown or mouseUp event. Likewise for dead key events. This
- calls ConvertEventRefToEventRecord, but then checks to see if it is
- a mouse up/down, or a dead key Carbon event that has not been
- converted, and if so, converts it by hand (to be picked up in the
- XTread_socket loop). */
-static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
-{
- OSStatus err;
- Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec);
- EventKind action;
-
- if (result)
- return result;
-
- switch (GetEventClass (eventRef))
- {
- case kEventClassMouse:
- switch (GetEventKind (eventRef))
- {
- case kEventMouseDown:
- eventRec->what = mouseDown;
- result = 1;
- break;
-
- case kEventMouseUp:
- eventRec->what = mouseUp;
- result = 1;
- break;
-
- default:
- break;
- }
- break;
-
- case kEventClassKeyboard:
- switch (GetEventKind (eventRef))
+ if (NILP (Vtransient_mark_mode) || NILP (b->mark_active))
+ end = start;
+ else
{
- case kEventRawKeyDown:
- action = keyDown;
- goto keystroke_common;
- case kEventRawKeyRepeat:
- action = autoKey;
- goto keystroke_common;
- case kEventRawKeyUp:
- action = keyUp;
- keystroke_common:
- {
- unsigned char char_codes;
- UInt32 key_code;
-
- err = GetEventParameter (eventRef, kEventParamKeyMacCharCodes,
- typeChar, NULL, sizeof (char),
- NULL, &char_codes);
- if (err == noErr)
- err = GetEventParameter (eventRef, kEventParamKeyCode,
- typeUInt32, NULL, sizeof (UInt32),
- NULL, &key_code);
- if (err == noErr)
- {
- eventRec->what = action;
- eventRec->message = char_codes | ((key_code & 0xff) << 8);
- result = 1;
- }
- }
- break;
+ int mark_pos = marker_position (b->mark);
- default:
- break;
+ if (start <= mark_pos)
+ end = mark_pos;
+ else
+ {
+ end = start;
+ start = mark_pos;
+ }
}
- break;
-
- default:
- break;
}
- if (result)
+ if (start != end)
{
- /* Need where and when. */
- UInt32 mods = 0;
+ if (start < begv)
+ start = begv;
+ else if (start > zv)
+ start = zv;
- GetEventParameter (eventRef, kEventParamMouseLocation, typeQDPoint,
- NULL, sizeof (Point), NULL, &eventRec->where);
- /* Use two step process because new event modifiers are 32-bit
- and old are 16-bit. Currently, only loss is NumLock & Fn. */
- GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32,
- NULL, sizeof (UInt32), NULL, &mods);
- eventRec->modifiers = mods;
-
- eventRec->when = EventTimeToTicks (GetEventTime (eventRef));
+ if (end < begv)
+ end = begv;
+ else if (end > zv)
+ end = zv;
}
- return result;
+ range->location = start - begv;
+ range->length = end - start;
}
-#endif
+/* Store the text of the buffer BUF from START to END as Unicode
+ characters in CHARACTERS. Return non-zero if successful. */
-#ifdef MAC_OS8
-static void
-do_get_menus (void)
+int
+mac_store_buffer_text_to_unicode_chars (buf, start, end, characters)
+ struct buffer *buf;
+ int start, end;
+ UniChar *characters;
{
- Handle menubar_handle;
- MenuHandle menu_handle;
+ int start_byte, end_byte, char_count, byte_count;
+ struct coding_system coding;
+ unsigned char *dst = (unsigned char *) characters;
- menubar_handle = GetNewMBar (128);
- if(menubar_handle == NULL)
- abort ();
- SetMenuBar (menubar_handle);
- DrawMenuBar ();
+ start_byte = buf_charpos_to_bytepos (buf, start);
+ end_byte = buf_charpos_to_bytepos (buf, end);
+ char_count = end - start;
+ byte_count = end_byte - start_byte;
-#if !TARGET_API_MAC_CARBON
- menu_handle = GetMenuHandle (M_APPLE);
- if(menu_handle != NULL)
- AppendResMenu (menu_handle,'DRVR');
- else
- abort ();
+ if (setup_coding_system (
+#ifdef WORDS_BIG_ENDIAN
+ intern ("utf-16be")
+#else
+ intern ("utf-16le")
#endif
-}
-
+ , &coding) < 0)
+ return 0;
-static void
-do_init_managers (void)
-{
-#if !TARGET_API_MAC_CARBON
- InitGraf (&qd.thePort);
- InitFonts ();
- FlushEvents (everyEvent, 0);
- InitWindows ();
- InitMenus ();
- TEInit ();
- InitDialogs (NULL);
-#endif /* !TARGET_API_MAC_CARBON */
- InitCursor ();
+ coding.src_multibyte = !NILP (buf->enable_multibyte_characters);
+ coding.dst_multibyte = 0;
+ coding.mode |= CODING_MODE_LAST_BLOCK;
+ coding.composing = COMPOSITION_DISABLED;
-#if !TARGET_API_MAC_CARBON
- /* set up some extra stack space for use by emacs */
- SetApplLimit ((Ptr) ((long) GetApplLimit () - EXTRA_STACK_ALLOC));
+ if (BUF_GPT_BYTE (buf) <= start_byte || end_byte <= BUF_GPT_BYTE (buf))
+ encode_coding (&coding, BUF_BYTE_ADDRESS (buf, start_byte), dst,
+ byte_count, char_count * sizeof (UniChar));
+ else
+ {
+ int first_byte_count = BUF_GPT_BYTE (buf) - start_byte;
- /* MaxApplZone must be called for AppleScript to execute more
- complicated scripts */
- MaxApplZone ();
- MoreMasters ();
-#endif /* !TARGET_API_MAC_CARBON */
-}
+ encode_coding (&coding, BUF_BYTE_ADDRESS (buf, start_byte), dst,
+ first_byte_count, char_count * sizeof (UniChar));
+ if (coding.result == CODING_FINISH_NORMAL)
+ encode_coding (&coding,
+ BUF_BYTE_ADDRESS (buf, start_byte + first_byte_count),
+ dst + coding.produced,
+ byte_count - first_byte_count,
+ char_count * sizeof (UniChar) - coding.produced);
+ }
-static void
-do_check_ram_size (void)
-{
- SInt32 physical_ram_size, logical_ram_size;
+ if (coding.result != CODING_FINISH_NORMAL)
+ return 0;
- if (Gestalt (gestaltPhysicalRAMSize, &physical_ram_size) != noErr
- || Gestalt (gestaltLogicalRAMSize, &logical_ram_size) != noErr
- || physical_ram_size > (1 << VALBITS)
- || logical_ram_size > (1 << VALBITS))
- {
- StopAlert (RAM_TOO_LARGE_ALERT_ID, NULL);
- exit (1);
- }
+ return 1;
}
-#endif /* MAC_OS8 */
-static void
-do_window_update (WindowPtr win)
+void
+mac_ax_selected_text_range (f, range)
+ struct frame *f;
+ CFRange *range;
{
- struct frame *f = mac_window_to_frame (win);
-
- BeginUpdate (win);
-
- /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED
- below. */
- if (win != tip_window)
- {
- if (f->async_visible == 0)
- {
- /* Update events may occur when a frame gets iconified. */
-#if 0
- f->async_visible = 1;
- f->async_iconified = 0;
- SET_FRAME_GARBAGED (f);
-#endif
- }
- else
- {
- Rect r;
-#if TARGET_API_MAC_CARBON
- RgnHandle region = NewRgn ();
-
- GetPortVisibleRegion (GetWindowPort (win), region);
- GetRegionBounds (region, &r);
- expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- UpdateControls (win, region);
- DisposeRgn (region);
-#else
- r = (*win->visRgn)->rgnBBox;
- expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
- UpdateControls (win, win->visRgn);
-#endif
- }
- }
-
- EndUpdate (win);
+ mac_get_selected_range (XWINDOW (f->selected_window), range);
}
-static int
-is_emacs_window (WindowPtr win)
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+unsigned int
+mac_ax_number_of_characters (f)
+ struct frame *f;
{
- Lisp_Object tail, frame;
-
- if (!win)
- return 0;
+ struct buffer *b = XBUFFER (XWINDOW (f->selected_window)->buffer);
- FOR_EACH_FRAME (tail, frame)
- if (FRAME_MAC_P (XFRAME (frame)))
- if (FRAME_MAC_WINDOW (XFRAME (frame)) == win)
- return 1;
-
- return 0;
+ return BUF_ZV (b) - BUF_BEGV (b);
}
+#endif
+#endif
#if USE_MAC_TSM
-static OSStatus
-mac_tsm_resume ()
+OSStatus
+mac_restore_keyboard_input_source ()
{
- OSStatus err;
+ OSStatus err = noErr;
ScriptLanguageRecord slrec, *slptr = NULL;
- err = ActivateTSMDocument (tsm_document_id);
-
- if (err == noErr)
+ if (EQ (Vmac_ts_script_language_on_focus, Qt)
+ && EQ (saved_ts_script_language_on_focus, Qt))
+ slptr = &saved_ts_language;
+ else if (CONSP (Vmac_ts_script_language_on_focus)
+ && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
+ && INTEGERP (XCDR (Vmac_ts_script_language_on_focus))
+ && CONSP (saved_ts_script_language_on_focus)
+ && EQ (XCAR (saved_ts_script_language_on_focus),
+ XCAR (Vmac_ts_script_language_on_focus))
+ && EQ (XCDR (saved_ts_script_language_on_focus),
+ XCDR (Vmac_ts_script_language_on_focus)))
{
- if (EQ (Vmac_ts_script_language_on_focus, Qt)
- && EQ (saved_ts_script_language_on_focus, Qt))
- slptr = &saved_ts_language;
- else if (CONSP (Vmac_ts_script_language_on_focus)
- && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
- && INTEGERP (XCDR (Vmac_ts_script_language_on_focus))
- && CONSP (saved_ts_script_language_on_focus)
- && EQ (XCAR (saved_ts_script_language_on_focus),
- XCAR (Vmac_ts_script_language_on_focus))
- && EQ (XCDR (saved_ts_script_language_on_focus),
- XCDR (Vmac_ts_script_language_on_focus)))
- {
- slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
- slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
- slptr = &slrec;
- }
+ slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
+ slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
+ slptr = &slrec;
}
if (slptr)
return err;
}
-static OSStatus
-mac_tsm_suspend ()
+void
+mac_save_keyboard_input_source ()
{
OSStatus err;
ScriptLanguageRecord slrec, *slptr = NULL;
GetDefaultInputMethod (&saved_ts_component, slptr);
#endif
}
-
- err = DeactivateTSMDocument (tsm_document_id);
-
- return err;
-}
-#endif
-
-#if !TARGET_API_MAC_CARBON
-void
-do_apple_menu (SInt16 menu_item)
-{
- Str255 item_name;
- SInt16 da_driver_refnum;
-
- if (menu_item == I_ABOUT)
- NoteAlert (ABOUT_ALERT_ID, NULL);
- else
- {
- GetMenuItemText (GetMenuHandle (M_APPLE), menu_item, item_name);
- da_driver_refnum = OpenDeskAcc (item_name);
- }
}
-#endif /* !TARGET_API_MAC_CARBON */
-
-/* Handle drags in size box. Based on code contributed by Ben
- Mesander and IM - Window Manager A. */
-
-static void
-do_grow_window (w, e)
- WindowPtr w;
- const EventRecord *e;
-{
- Rect limit_rect;
- int rows, columns, width, height;
- struct frame *f = mac_window_to_frame (w);
- XSizeHints *size_hints = FRAME_SIZE_HINTS (f);
- int min_width = MIN_DOC_SIZE, min_height = MIN_DOC_SIZE;
-#if TARGET_API_MAC_CARBON
- Rect new_rect;
-#else
- long grow_size;
#endif
- if (size_hints->flags & PMinSize)
- {
- min_width = size_hints->min_width;
- min_height = size_hints->min_height;
- }
- SetRect (&limit_rect, min_width, min_height, MAX_DOC_SIZE, MAX_DOC_SIZE);
-
#if TARGET_API_MAC_CARBON
- if (!ResizeWindow (w, e->where, &limit_rect, &new_rect))
- return;
- height = new_rect.bottom - new_rect.top;
- width = new_rect.right - new_rect.left;
-#else
- grow_size = GrowWindow (w, e->where, &limit_rect);
- /* see if it really changed size */
- if (grow_size == 0)
- return;
- height = HiWord (grow_size);
- width = LoWord (grow_size);
-#endif
-
- if (width != FRAME_PIXEL_WIDTH (f)
- || height != FRAME_PIXEL_HEIGHT (f))
- {
- rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
- columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
+/***** Code to handle C-g testing *****/
+extern int quit_char;
+extern int make_ctrl_char P_ ((int));
- x_set_window_size (f, 0, columns, rows);
- }
-}
+int
+mac_quit_char_key_p (modifiers, key_code)
+ UInt32 modifiers, key_code;
+{
+ UInt32 char_code, mapped_modifiers;
+ unsigned long some_state = 0;
+ Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+ int c, emacs_modifiers;
+ /* Mask off modifier keys that are mapped to some Emacs modifiers. */
+ mapped_modifiers = mac_mapped_modifiers (modifiers, key_code);
+ key_code |= (modifiers & ~mapped_modifiers);
+ char_code = KeyTranslate (kchr_ptr, key_code, &some_state);
+ if (char_code & ~0xff)
+ return 0;
-#if TARGET_API_MAC_CARBON
-static Point
-mac_get_ideal_size (f)
- struct frame *f;
-{
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- WindowPtr w = FRAME_MAC_WINDOW (f);
- Point ideal_size;
- Rect standard_rect;
- int height, width, columns, rows;
+ emacs_modifiers = mac_to_emacs_modifiers (mapped_modifiers, modifiers);
+ if (emacs_modifiers & ctrl_modifier)
+ c = make_ctrl_char (char_code);
- ideal_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
- ideal_size.v = dpyinfo->height;
- IsWindowInStandardState (w, &ideal_size, &standard_rect);
- /* Adjust the standard size according to character boundaries. */
- width = standard_rect.right - standard_rect.left;
- height = standard_rect.bottom - standard_rect.top;
- columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
- rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
- ideal_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, columns);
- ideal_size.v = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+ c |= (emacs_modifiers
+ & (meta_modifier | alt_modifier
+ | hyper_modifier | super_modifier));
- return ideal_size;
+ return c == quit_char;
}
#endif
-/* Handle clicks in zoom box. Calculation of "standard state" based
- on code in IM - Window Manager A and code contributed by Ben
- Mesander. The standard state of an Emacs window is 80-characters
- wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
-
static void
-do_zoom_window (WindowPtr w, int zoom_in_or_out)
+mac_set_unicode_keystroke_event (code, buf)
+ UniChar code;
+ struct input_event *buf;
{
- Rect zoom_rect, port_rect;
- int width, height;
- struct frame *f = mac_window_to_frame (w);
-#if TARGET_API_MAC_CARBON
- Point ideal_size = mac_get_ideal_size (f);
-
- GetWindowBounds (w, kWindowContentRgn, &port_rect);
- if (IsWindowInStandardState (w, &ideal_size, &zoom_rect)
- && port_rect.left == zoom_rect.left
- && port_rect.top == zoom_rect.top)
- zoom_in_or_out = inZoomIn;
- else
- zoom_in_or_out = inZoomOut;
+ int charset_id, c1, c2;
-#ifdef MAC_OS8
- mac_clear_window (f);
-#endif
- ZoomWindowIdeal (w, zoom_in_or_out, &ideal_size);
-#else /* not TARGET_API_MAC_CARBON */
- GrafPtr save_port;
- Point top_left;
- int w_title_height, rows;
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+ if (code < 0x80)
+ {
+ buf->kind = ASCII_KEYSTROKE_EVENT;
+ buf->code = code;
+ }
+ else if (code < 0x100)
+ {
+ if (code < 0xA0)
+ charset_id = CHARSET_8_BIT_CONTROL;
+ else
+ charset_id = charset_latin_iso8859_1;
+ buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+ buf->code = MAKE_CHAR (charset_id, code, 0);
+ }
+ else
+ {
+ if (code < 0x2500)
+ charset_id = charset_mule_unicode_0100_24ff,
+ code -= 0x100;
+ else if (code < 0x33FF)
+ charset_id = charset_mule_unicode_2500_33ff,
+ code -= 0x2500;
+ else if (code >= 0xE000)
+ charset_id = charset_mule_unicode_e000_ffff,
+ code -= 0xE000;
+ c1 = (code / 96) + 32, c2 = (code % 96) + 32;
+ buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+ buf->code = MAKE_CHAR (charset_id, c1, c2);
+ }
+}
- GetPort (&save_port);
+void
+do_keystroke (action, char_code, key_code, modifiers, timestamp, buf)
+ EventKind action;
+ unsigned char char_code;
+ UInt32 key_code, modifiers;
+ unsigned long timestamp;
+ struct input_event *buf;
+{
+ static SInt16 last_key_script = -1;
+ SInt16 current_key_script = GetScriptManagerVariable (smKeyScript);
+ UInt32 mapped_modifiers = mac_mapped_modifiers (modifiers, key_code);
- SetPortWindowPort (w);
+#ifdef MAC_OSX
+ if (mapped_modifiers & kEventKeyModifierFnMask
+ && key_code <= 0x7f
+ && fn_keycode_to_keycode_table[key_code])
+ key_code = fn_keycode_to_keycode_table[key_code];
+#endif
- /* Clear window to avoid flicker. */
- EraseRect (&(w->portRect));
- if (zoom_in_or_out == inZoomOut)
+ if (key_code <= 0x7f && keycode_to_xkeysym_table[key_code])
{
- SetPt (&top_left, w->portRect.left, w->portRect.top);
- LocalToGlobal (&top_left);
-
- /* calculate height of window's title bar */
- w_title_height = top_left.v - 1
- - (**((WindowPeek) w)->strucRgn).rgnBBox.top + GetMBarHeight ();
+ buf->kind = NON_ASCII_KEYSTROKE_EVENT;
+ buf->code = 0xff00 | keycode_to_xkeysym_table[key_code];
+ }
+ else if (mapped_modifiers)
+ {
+ /* translate the keycode back to determine the original key */
+#ifdef MAC_OSX
+ UCKeyboardLayout *uchr_ptr = NULL;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ OSStatus err;
+ KeyboardLayoutRef layout;
- /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
- zoom_rect = qd.screenBits.bounds;
- zoom_rect.top += w_title_height;
- InsetRect (&zoom_rect, 8, 4); /* not too tight */
+ err = KLGetCurrentKeyboardLayout (&layout);
+ if (err == noErr)
+ err = KLGetKeyboardLayoutProperty (layout, kKLuchrData,
+ (const void **) &uchr_ptr);
+#else
+ static SInt16 last_key_layout_id = 0;
+ static Handle uchr_handle = (Handle)-1;
+ SInt16 current_key_layout_id =
+ GetScriptVariable (current_key_script, smScriptKeys);
- zoom_rect.right = zoom_rect.left
- + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
+ if (uchr_handle == (Handle)-1
+ || last_key_layout_id != current_key_layout_id)
+ {
+ uchr_handle = GetResource ('uchr', current_key_layout_id);
+ last_key_layout_id = current_key_layout_id;
+ }
+ if (uchr_handle)
+ uchr_ptr = (UCKeyboardLayout *)*uchr_handle;
+#endif
- /* Adjust the standard size according to character boundaries. */
- rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, zoom_rect.bottom - zoom_rect.top);
- zoom_rect.bottom =
- zoom_rect.top + FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+ if (uchr_ptr)
+ {
+ OSStatus status;
+ UInt16 key_action = action - keyDown;
+ UInt32 modifier_key_state = (modifiers & ~mapped_modifiers) >> 8;
+ UInt32 keyboard_type = LMGetKbdType ();
+ SInt32 dead_key_state = 0;
+ UniChar code;
+ UniCharCount actual_length;
+
+ status = UCKeyTranslate (uchr_ptr, key_code, key_action,
+ modifier_key_state, keyboard_type,
+ kUCKeyTranslateNoDeadKeysMask,
+ &dead_key_state,
+ 1, &actual_length, &code);
+ if (status == noErr && actual_length == 1)
+ mac_set_unicode_keystroke_event (code, buf);
+ }
+#endif /* MAC_OSX */
- (**((WStateDataHandle) ((WindowPeek) w)->dataHandle)).stdState
- = zoom_rect;
+ if (buf->kind == NO_EVENT)
+ {
+ /* This code comes from Keyboard Resource, Appendix C of IM
+ - Text. This is necessary since shift is ignored in KCHR
+ table translation when option or command is pressed. It
+ also does not translate correctly control-shift chars
+ like C-% so mask off shift here also. */
+ /* Mask off modifier keys that are mapped to some Emacs
+ modifiers. */
+ int new_modifiers = modifiers & ~mapped_modifiers;
+ /* set high byte of keycode to modifier high byte*/
+ int new_key_code = key_code | new_modifiers;
+ Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+ unsigned long some_state = 0;
+ UInt32 new_char_code;
+
+ new_char_code = KeyTranslate (kchr_ptr, new_key_code, &some_state);
+ if (new_char_code == 0)
+ /* Seems like a dead key. Append up-stroke. */
+ new_char_code = KeyTranslate (kchr_ptr, new_key_code | 0x80,
+ &some_state);
+ if (new_char_code)
+ {
+ buf->kind = ASCII_KEYSTROKE_EVENT;
+ buf->code = new_char_code & 0xff;
+ }
+ }
}
- ZoomWindow (w, zoom_in_or_out, f == mac_focus_frame (dpyinfo));
+ if (buf->kind == NO_EVENT)
+ {
+ buf->kind = ASCII_KEYSTROKE_EVENT;
+ buf->code = char_code;
+ }
- SetPort (save_port);
-#endif /* not TARGET_API_MAC_CARBON */
+ buf->modifiers = mac_to_emacs_modifiers (mapped_modifiers, modifiers);
+ buf->modifiers |= (extra_keyboard_modifiers
+ & (meta_modifier | alt_modifier
+ | hyper_modifier | super_modifier));
-#if !USE_CARBON_EVENTS
- /* retrieve window size and update application values */
#if TARGET_API_MAC_CARBON
- GetWindowPortBounds (w, &port_rect);
-#else
- port_rect = w->portRect;
+ if (buf->kind == ASCII_KEYSTROKE_EVENT
+ && buf->code >= 0x80 && buf->modifiers)
+ {
+ OSStatus err;
+ TextEncoding encoding = kTextEncodingMacRoman;
+ TextToUnicodeInfo ttu_info;
+
+ UpgradeScriptInfoToTextEncoding (current_key_script,
+ kTextLanguageDontCare,
+ kTextRegionDontCare,
+ NULL, &encoding);
+ err = CreateTextToUnicodeInfoByEncoding (encoding, &ttu_info);
+ if (err == noErr)
+ {
+ UniChar code;
+ Str255 pstr;
+ ByteCount unicode_len;
+
+ pstr[0] = 1;
+ pstr[1] = buf->code;
+ err = ConvertFromPStringToUnicode (ttu_info, pstr,
+ sizeof (UniChar),
+ &unicode_len, &code);
+ if (err == noErr && unicode_len == sizeof (UniChar))
+ mac_set_unicode_keystroke_event (code, buf);
+ DisposeTextToUnicodeInfo (&ttu_info);
+ }
+ }
#endif
- height = port_rect.bottom - port_rect.top;
- width = port_rect.right - port_rect.left;
- mac_handle_size_change (f, width, height);
- mac_handle_origin_change (f);
-#endif
+ if (buf->kind == ASCII_KEYSTROKE_EVENT
+ && buf->code >= 0x80
+ && last_key_script != current_key_script)
+ {
+ struct input_event event;
+
+ EVENT_INIT (event);
+ event.kind = LANGUAGE_CHANGE_EVENT;
+ event.arg = Qnil;
+ event.code = current_key_script;
+ event.timestamp = timestamp;
+ kbd_buffer_store_event (&event);
+ last_key_script = current_key_script;
+ }
}
void
}
#if TARGET_API_MAC_CARBON
-static OSStatus
+OSStatus
mac_store_event_ref_as_apple_event (class, id, class_key, id_key,
event, num_params, names, types)
AEEventClass class;
err = XINT (binding);
else
{
- AppleEvent apple_event;
- err = create_apple_event_from_event_ref (event, num_params,
- names, types,
- &apple_event);
- if (err == noErr)
- {
- mac_store_apple_event (class_key, id_key, &apple_event);
- AEDisposeDesc (&apple_event);
- mac_wakeup_from_rne ();
- }
+ struct input_event buf;
+
+ EVENT_INIT (buf);
+
+ buf.kind = MAC_APPLE_EVENT;
+ buf.x = class_key;
+ buf.y = id_key;
+ XSETFRAME (buf.frame_or_window,
+ mac_focus_frame (&one_mac_display_info));
+ /* Now that Lisp object allocations are protected by
+ BLOCK_INPUT, it is safe to use them during
+ read_socket_hook. */
+ buf.arg = Fcons (build_string ("aevt"),
+ mac_event_parameters_to_lisp (event, num_params,
+ names, types));
+ kbd_buffer_store_event (&buf);
+ mac_wakeup_from_rne ();
+ err = noErr;
}
}
return err;
}
+#endif /* TARGET_API_MAC_CARBON */
-void
-mac_store_drag_event (window, mouse_pos, modifiers, desc)
- WindowRef window;
- Point mouse_pos;
- SInt16 modifiers;
- const AEDesc *desc;
-{
- struct input_event buf;
-
- EVENT_INIT (buf);
-
- buf.kind = DRAG_N_DROP_EVENT;
- buf.modifiers = mac_to_emacs_modifiers (modifiers, 0);
- buf.timestamp = TickCount () * (1000 / 60);
- XSETINT (buf.x, mouse_pos.h);
- XSETINT (buf.y, mouse_pos.v);
- XSETFRAME (buf.frame_or_window, mac_window_to_frame (window));
- buf.arg = mac_aedesc_to_lisp (desc);
- kbd_buffer_store_event (&buf);
-}
-#endif
-
-#if USE_CARBON_EVENTS
-static pascal OSStatus
-mac_handle_command_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
+static pascal void
+mac_handle_dm_notification (event)
+ AppleEvent *event;
{
- OSStatus result, err;
- HICommand command;
- static const EventParamName names[] =
- {kEventParamDirectObject, kEventParamKeyModifiers};
- static const EventParamType types[] =
- {typeHICommand, typeUInt32};
- int num_params = sizeof (names) / sizeof (names[0]);
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
-
- err = GetEventParameter (event, kEventParamDirectObject, typeHICommand,
- NULL, sizeof (HICommand), NULL, &command);
-
- if (err != noErr || command.commandID == 0)
- return eventNotHandledErr;
-
- /* A HI command event is mapped to an Apple event whose event class
- symbol is `hi-command' and event ID is its command ID. */
- err = mac_store_event_ref_as_apple_event (0, command.commandID,
- Qhi_command, Qnil,
- event, num_params, names, types);
- return err == noErr ? noErr : eventNotHandledErr;
+ mac_screen_config_changed = 1;
}
-static OSStatus
-init_command_handler ()
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+static void
+mac_handle_cg_display_reconfig (display, flags, user_info)
+ CGDirectDisplayID display;
+ CGDisplayChangeSummaryFlags flags;
+ void *user_info;
{
- static const EventTypeSpec specs[] =
- {{kEventClassCommand, kEventCommandProcess}};
- static EventHandlerUPP handle_command_eventUPP = NULL;
-
- if (handle_command_eventUPP == NULL)
- handle_command_eventUPP = NewEventHandlerUPP (mac_handle_command_event);
- return InstallApplicationEventHandler (handle_command_eventUPP,
- GetEventTypeCount (specs), specs,
- NULL, NULL);
+ mac_screen_config_changed = 1;
}
-
-static pascal OSStatus
-mac_handle_window_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- WindowPtr wp;
- OSStatus result, err;
- struct frame *f;
- UInt32 attributes;
- XSizeHints *size_hints;
-
- err = GetEventParameter (event, kEventParamDirectObject, typeWindowRef,
- NULL, sizeof (WindowPtr), NULL, &wp);
- if (err != noErr)
- return eventNotHandledErr;
-
- f = mac_window_to_frame (wp);
- switch (GetEventKind (event))
- {
- case kEventWindowUpdate:
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
-
- do_window_update (wp);
- return noErr;
-
- case kEventWindowGetIdealSize:
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
-
- {
- Point ideal_size = mac_get_ideal_size (f);
-
- err = SetEventParameter (event, kEventParamDimensions,
- typeQDPoint, sizeof (Point), &ideal_size);
- if (err == noErr)
- return noErr;
- }
- break;
-
- case kEventWindowBoundsChanging:
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
-
- err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
- NULL, sizeof (UInt32), NULL, &attributes);
- if (err != noErr)
- break;
-
- size_hints = FRAME_SIZE_HINTS (f);
- if ((attributes & kWindowBoundsChangeUserResize)
- && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize))
- == (PResizeInc | PBaseSize | PMinSize)))
- {
- Rect bounds;
- int width, height;
-
- err = GetEventParameter (event, kEventParamCurrentBounds,
- typeQDRectangle, NULL, sizeof (Rect),
- NULL, &bounds);
- if (err != noErr)
- break;
-
- width = bounds.right - bounds.left;
- height = bounds.bottom - bounds.top;
-
- if (width < size_hints->min_width)
- width = size_hints->min_width;
- else
- width = size_hints->base_width
- + (int) ((width - size_hints->base_width)
- / (float) size_hints->width_inc + .5)
- * size_hints->width_inc;
-
- if (height < size_hints->min_height)
- height = size_hints->min_height;
- else
- height = size_hints->base_height
- + (int) ((height - size_hints->base_height)
- / (float) size_hints->height_inc + .5)
- * size_hints->height_inc;
-
- bounds.right = bounds.left + width;
- bounds.bottom = bounds.top + height;
- SetEventParameter (event, kEventParamCurrentBounds,
- typeQDRectangle, sizeof (Rect), &bounds);
- return noErr;
- }
- break;
-
- case kEventWindowBoundsChanged:
- err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
- NULL, sizeof (UInt32), NULL, &attributes);
- if (err != noErr)
- break;
-
- if (attributes & kWindowBoundsChangeSizeChanged)
- {
- Rect bounds;
-
- err = GetEventParameter (event, kEventParamCurrentBounds,
- typeQDRectangle, NULL, sizeof (Rect),
- NULL, &bounds);
- if (err == noErr)
- {
- int width, height;
-
- width = bounds.right - bounds.left;
- height = bounds.bottom - bounds.top;
- mac_handle_size_change (f, width, height);
- mac_wakeup_from_rne ();
- }
- }
-
- if (attributes & kWindowBoundsChangeOriginChanged)
- mac_handle_origin_change (f);
-
- return noErr;
-
- case kEventWindowShown:
- case kEventWindowHidden:
- case kEventWindowExpanded:
- case kEventWindowCollapsed:
- result = CallNextEventHandler (next_handler, event);
-
- mac_handle_visibility_change (f);
- return noErr;
-
- break;
-
- case kEventWindowClose:
- result = CallNextEventHandler (next_handler, event);
- {
- struct input_event buf;
-
- EVENT_INIT (buf);
- buf.kind = DELETE_WINDOW_EVENT;
- XSETFRAME (buf.frame_or_window, f);
- buf.arg = Qnil;
- kbd_buffer_store_event (&buf);
- }
- return noErr;
-
-#ifdef MAC_OSX
- case kEventWindowToolbarSwitchMode:
- result = CallNextEventHandler (next_handler, event);
- {
- static const EventParamName names[] = {kEventParamDirectObject,
- kEventParamWindowMouseLocation,
- kEventParamKeyModifiers,
- kEventParamMouseButton,
- kEventParamClickCount,
- kEventParamMouseChord};
- static const EventParamType types[] = {typeWindowRef,
- typeQDPoint,
- typeUInt32,
- typeMouseButton,
- typeUInt32,
- typeUInt32};
- int num_params = sizeof (names) / sizeof (names[0]);
-
- err = mac_store_event_ref_as_apple_event (0, 0,
- Qwindow,
- Qtoolbar_switch_mode,
- event, num_params,
- names, types);
- }
- return err == noErr ? noErr : result;
-#endif
-
-#if USE_MAC_TSM
- case kEventWindowFocusAcquired:
- result = CallNextEventHandler (next_handler, event);
- err = mac_tsm_resume ();
- return err == noErr ? noErr : result;
-
- case kEventWindowFocusRelinquish:
- result = CallNextEventHandler (next_handler, event);
- err = mac_tsm_suspend ();
- return err == noErr ? noErr : result;
#endif
- }
-
- return eventNotHandledErr;
-}
-static pascal OSStatus
-mac_handle_mouse_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
+static OSErr
+init_dm_notification_handler ()
{
- OSStatus result, err;
+ OSErr err = noErr;
- switch (GetEventKind (event))
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ if (CGDisplayRegisterReconfigurationCallback != NULL)
+#endif
{
- case kEventMouseWheelMoved:
- {
- WindowPtr wp;
- struct frame *f;
- EventMouseWheelAxis axis;
- SInt32 delta;
- Point point;
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr || read_socket_inev == NULL)
- return result;
-
- err = GetEventParameter (event, kEventParamWindowRef, typeWindowRef,
- NULL, sizeof (WindowRef), NULL, &wp);
- if (err != noErr)
- break;
-
- f = mac_window_to_frame (wp);
- if (f != mac_focus_frame (&one_mac_display_info))
- break;
-
- err = GetEventParameter (event, kEventParamMouseWheelAxis,
- typeMouseWheelAxis, NULL,
- sizeof (EventMouseWheelAxis), NULL, &axis);
- if (err != noErr || axis != kEventMouseWheelAxisY)
- break;
-
- err = GetEventParameter (event, kEventParamMouseLocation,
- typeQDPoint, NULL, sizeof (Point),
- NULL, &point);
- if (err != noErr)
- break;
-
- SetPortWindowPort (wp);
- GlobalToLocal (&point);
- if (point.h < 0 || point.v < 0
- || EQ (window_from_coordinates (f, point.h, point.v, 0, 0, 0, 1),
- f->tool_bar_window))
- break;
-
- err = GetEventParameter (event, kEventParamMouseWheelDelta,
- typeSInt32, NULL, sizeof (SInt32),
- NULL, &delta);
- if (err != noErr)
- break;
-
- read_socket_inev->kind = WHEEL_EVENT;
- read_socket_inev->code = 0;
- read_socket_inev->modifiers =
- (mac_event_to_emacs_modifiers (event)
- | ((delta < 0) ? down_modifier : up_modifier));
- XSETINT (read_socket_inev->x, point.h);
- XSETINT (read_socket_inev->y, point.v);
- XSETFRAME (read_socket_inev->frame_or_window, f);
-
- return noErr;
- }
- break;
-
- default:
- break;
+ CGDisplayRegisterReconfigurationCallback (mac_handle_cg_display_reconfig,
+ NULL);
}
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ else /* CGDisplayRegisterReconfigurationCallback == NULL */
+#endif
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ {
+ static DMNotificationUPP handle_dm_notificationUPP = NULL;
+ ProcessSerialNumber psn;
- return eventNotHandledErr;
-}
-
-#if USE_MAC_FONT_PANEL
-static pascal OSStatus
-mac_handle_font_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus result, err;
- Lisp_Object id_key;
- int num_params;
- const EventParamName *names;
- const EventParamType *types;
- static const EventParamName names_sel[] = {kEventParamATSUFontID,
- kEventParamATSUFontSize,
- kEventParamFMFontFamily,
- kEventParamFMFontSize,
- kEventParamFontColor};
- static const EventParamType types_sel[] = {typeATSUFontID,
- typeATSUSize,
- typeFMFontFamily,
- typeFMFontSize,
- typeFontColor};
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
-
- switch (GetEventKind (event))
- {
- case kEventFontPanelClosed:
- id_key = Qpanel_closed;
- num_params = 0;
- names = NULL;
- types = NULL;
- break;
+ if (handle_dm_notificationUPP == NULL)
+ handle_dm_notificationUPP =
+ NewDMNotificationUPP (mac_handle_dm_notification);
- case kEventFontSelection:
- id_key = Qselection;
- num_params = sizeof (names_sel) / sizeof (names_sel[0]);
- names = names_sel;
- types = types_sel;
- break;
+ err = GetCurrentProcess (&psn);
+ if (err == noErr)
+ err = DMRegisterNotifyProc (handle_dm_notificationUPP, &psn);
}
+#endif
- err = mac_store_event_ref_as_apple_event (0, 0, Qfont, id_key,
- event, num_params,
- names, types);
-
- return err == noErr ? noErr : eventNotHandledErr;
+ return err;
}
-#endif
-#if USE_MAC_TSM
-static pascal OSStatus
-mac_handle_text_input_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus result, err = noErr;
- Lisp_Object id_key = Qnil;
- int num_params;
- const EventParamName *names;
- const EventParamType *types;
- static UInt32 seqno_uaia = 0;
- static const EventParamName names_uaia[] =
- {kEventParamTextInputSendComponentInstance,
- kEventParamTextInputSendRefCon,
- kEventParamTextInputSendSLRec,
- kEventParamTextInputSendFixLen,
- kEventParamTextInputSendText,
- kEventParamTextInputSendUpdateRng,
- kEventParamTextInputSendHiliteRng,
- kEventParamTextInputSendClauseRng,
- kEventParamTextInputSendPinRng,
- kEventParamTextInputSendTextServiceEncoding,
- kEventParamTextInputSendTextServiceMacEncoding,
- EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER};
- static const EventParamType types_uaia[] =
- {typeComponentInstance,
- typeLongInteger,
- typeIntlWritingCode,
- typeLongInteger,
+void
+mac_get_screen_info (dpyinfo)
+ struct mac_display_info *dpyinfo;
+{
#ifdef MAC_OSX
- typeUnicodeText,
-#else
- typeChar,
-#endif
- typeTextRangeArray,
- typeTextRangeArray,
- typeOffsetArray,
- typeTextRange,
- typeUInt32,
- typeUInt32,
- typeUInt32};
- static const EventParamName names_ufke[] =
- {kEventParamTextInputSendComponentInstance,
- kEventParamTextInputSendRefCon,
- kEventParamTextInputSendSLRec,
- kEventParamTextInputSendText};
- static const EventParamType types_ufke[] =
- {typeComponentInstance,
- typeLongInteger,
- typeIntlWritingCode,
- typeUnicodeText};
-
- result = CallNextEventHandler (next_handler, event);
-
- switch (GetEventKind (event))
- {
- case kEventTextInputUpdateActiveInputArea:
- id_key = Qupdate_active_input_area;
- num_params = sizeof (names_uaia) / sizeof (names_uaia[0]);
- names = names_uaia;
- types = types_uaia;
- SetEventParameter (event, EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER,
- typeUInt32, sizeof (UInt32), &seqno_uaia);
- seqno_uaia++;
- break;
+ /* HasDepth returns true if it is possible to have a 32 bit display,
+ but this may not be what is actually used. Mac OSX can do better. */
+ dpyinfo->color_p = CGDisplaySamplesPerPixel (kCGDirectMainDisplay) > 1;
+ dpyinfo->n_planes = CGDisplayBitsPerPixel (kCGDirectMainDisplay);
+ {
+ CGDisplayErr err;
+ CGDisplayCount ndisps;
+ CGDirectDisplayID *displays;
- case kEventTextInputUnicodeForKeyEvent:
+ err = CGGetActiveDisplayList (0, NULL, &ndisps);
+ if (err == noErr)
{
- EventRef kbd_event;
- UInt32 actual_size, modifiers, key_code;
-
- err = GetEventParameter (event, kEventParamTextInputSendKeyboardEvent,
- typeEventRef, NULL, sizeof (EventRef), NULL,
- &kbd_event);
- if (err == noErr)
- err = GetEventParameter (kbd_event, kEventParamKeyModifiers,
- typeUInt32, NULL,
- sizeof (UInt32), NULL, &modifiers);
- if (err == noErr)
- err = GetEventParameter (kbd_event, kEventParamKeyCode,
- typeUInt32, NULL, sizeof (UInt32),
- NULL, &key_code);
- if (err == noErr && mac_mapped_modifiers (modifiers, key_code))
- /* There're mapped modifier keys. Process it in
- XTread_socket. */
- return eventNotHandledErr;
- if (err == noErr)
- err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
- typeUnicodeText, NULL, 0, &actual_size,
- NULL);
- if (err == noErr && actual_size == sizeof (UniChar))
- {
- UniChar code;
-
- err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
- typeUnicodeText, NULL,
- sizeof (UniChar), NULL, &code);
- if (err == noErr && code < 0x80)
- {
- /* ASCII character. Process it in XTread_socket. */
- if (read_socket_inev && code >= 0x20 && code <= 0x7e
- && !(key_code <= 0x7f
- && keycode_to_xkeysym_table [key_code]))
- {
- struct frame *f = mac_focus_frame (&one_mac_display_info);
-
- read_socket_inev->kind = ASCII_KEYSTROKE_EVENT;
- read_socket_inev->code = code;
- read_socket_inev->modifiers =
- mac_to_emacs_modifiers (modifiers, 0);
- read_socket_inev->modifiers |=
- (extra_keyboard_modifiers
- & (meta_modifier | alt_modifier
- | hyper_modifier | super_modifier));
- XSETFRAME (read_socket_inev->frame_or_window, f);
- }
- return eventNotHandledErr;
- }
- }
+ displays = alloca (sizeof (CGDirectDisplayID) * ndisps);
+ err = CGGetActiveDisplayList (ndisps, displays, &ndisps);
}
- /* Non-ASCII keystrokes without mapped modifiers are processed
- at the Lisp level. */
- id_key = Qunicode_for_key_event;
- num_params = sizeof (names_ufke) / sizeof (names_ufke[0]);
- names = names_ufke;
- types = types_ufke;
- break;
-
- case kEventTextInputOffsetToPos:
+ if (err == noErr)
{
- struct frame *f;
- struct window *w;
- Point p;
-
- if (!OVERLAYP (Vmac_ts_active_input_overlay))
- return eventNotHandledErr;
-
- /* Strictly speaking, this is not always correct because
- previous events may change some states about display. */
- if (NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
- {
- if (!WINDOWP (echo_area_window))
- return eventNotHandledErr;
-
- /* Active input area is displayed in the echo area. */
- w = XWINDOW (echo_area_window);
- f = WINDOW_XFRAME (w);
- }
- else
- {
- /* Active input area is displayed around the current point. */
- f = SELECTED_FRAME ();
- w = XWINDOW (f->selected_window);
- }
+ CGRect bounds = CGRectZero;
- p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
- + WINDOW_LEFT_FRINGE_WIDTH (w));
- p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y)
- + FONT_BASE (FRAME_FONT (f)));
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
- LocalToGlobal (&p);
- err = SetEventParameter (event, kEventParamTextInputReplyPoint,
- typeQDPoint, sizeof (typeQDPoint), &p);
- }
- break;
-
- default:
- abort ();
- }
-
- if (!NILP (id_key))
- err = mac_store_event_ref_as_apple_event (0, 0, Qtext_input, id_key,
- event, num_params,
- names, types);
-
- return err == noErr ? noErr : result;
-}
-#endif
-
-#ifdef MAC_OSX
-OSStatus
-mac_store_service_event (event)
- EventRef event;
-{
- OSStatus err;
- Lisp_Object id_key;
- int num_params;
- const EventParamName *names;
- const EventParamType *types;
- static const EventParamName names_pfm[] =
- {kEventParamServiceMessageName, kEventParamServiceUserData};
- static const EventParamType types_pfm[] =
- {typeCFStringRef, typeCFStringRef};
-
- switch (GetEventKind (event))
- {
- case kEventServicePaste:
- id_key = Qpaste;
- num_params = 0;
- names = NULL;
- types = NULL;
- break;
-
- case kEventServicePerform:
- id_key = Qperform;
- num_params = sizeof (names_pfm) / sizeof (names_pfm[0]);
- names = names_pfm;
- types = types_pfm;
- break;
-
- default:
- abort ();
- }
-
- err = mac_store_event_ref_as_apple_event (0, 0, Qservice, id_key,
- event, num_params,
- names, types);
-
- return err;
-}
-#endif /* MAC_OSX */
-#endif /* USE_CARBON_EVENTS */
-
-
-OSStatus
-install_window_handler (window)
- WindowPtr window;
-{
- OSStatus err = noErr;
-#if USE_CARBON_EVENTS
- static const EventTypeSpec specs_window[] =
- {{kEventClassWindow, kEventWindowUpdate},
- {kEventClassWindow, kEventWindowGetIdealSize},
- {kEventClassWindow, kEventWindowBoundsChanging},
- {kEventClassWindow, kEventWindowBoundsChanged},
- {kEventClassWindow, kEventWindowShown},
- {kEventClassWindow, kEventWindowHidden},
- {kEventClassWindow, kEventWindowExpanded},
- {kEventClassWindow, kEventWindowCollapsed},
- {kEventClassWindow, kEventWindowClose},
-#ifdef MAC_OSX
- {kEventClassWindow, kEventWindowToolbarSwitchMode},
-#endif
-#if USE_MAC_TSM
- {kEventClassWindow, kEventWindowFocusAcquired},
- {kEventClassWindow, kEventWindowFocusRelinquish},
-#endif
- };
- static const EventTypeSpec specs_mouse[] =
- {{kEventClassMouse, kEventMouseWheelMoved}};
- static EventHandlerUPP handle_window_eventUPP = NULL;
- static EventHandlerUPP handle_mouse_eventUPP = NULL;
-#if USE_MAC_FONT_PANEL
- static const EventTypeSpec specs_font[] =
- {{kEventClassFont, kEventFontPanelClosed},
- {kEventClassFont, kEventFontSelection}};
- static EventHandlerUPP handle_font_eventUPP = NULL;
-#endif
-#if USE_MAC_TSM
- static const EventTypeSpec specs_text_input[] =
- {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
- {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
- {kEventClassTextInput, kEventTextInputOffsetToPos}};
- static EventHandlerUPP handle_text_input_eventUPP = NULL;
-#endif
-
- if (handle_window_eventUPP == NULL)
- handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event);
- if (handle_mouse_eventUPP == NULL)
- handle_mouse_eventUPP = NewEventHandlerUPP (mac_handle_mouse_event);
-#if USE_MAC_FONT_PANEL
- if (handle_font_eventUPP == NULL)
- handle_font_eventUPP = NewEventHandlerUPP (mac_handle_font_event);
-#endif
-#if USE_MAC_TSM
- if (handle_text_input_eventUPP == NULL)
- handle_text_input_eventUPP =
- NewEventHandlerUPP (mac_handle_text_input_event);
-#endif
- err = InstallWindowEventHandler (window, handle_window_eventUPP,
- GetEventTypeCount (specs_window),
- specs_window, NULL, NULL);
- if (err == noErr)
- err = InstallWindowEventHandler (window, handle_mouse_eventUPP,
- GetEventTypeCount (specs_mouse),
- specs_mouse, NULL, NULL);
-#if USE_MAC_FONT_PANEL
- if (err == noErr)
- err = InstallWindowEventHandler (window, handle_font_eventUPP,
- GetEventTypeCount (specs_font),
- specs_font, NULL, NULL);
-#endif
-#if USE_MAC_TSM
- if (err == noErr)
- err = InstallWindowEventHandler (window, handle_text_input_eventUPP,
- GetEventTypeCount (specs_text_input),
- specs_text_input, window, NULL);
-#endif
-#endif
- if (err == noErr)
- err = install_drag_handler (window);
- if (err == noErr)
- err = install_menu_target_item_handler (window);
-
- return err;
-}
-
-void
-remove_window_handler (window)
- WindowPtr window;
-{
- remove_drag_handler (window);
-}
-
-
-static pascal void
-mac_handle_dm_notification (event)
- AppleEvent *event;
-{
- mac_screen_config_changed = 1;
-}
-
-static OSErr
-init_dm_notification_handler ()
-{
- OSErr err;
- static DMNotificationUPP handle_dm_notificationUPP = NULL;
- ProcessSerialNumber psn;
-
- if (handle_dm_notificationUPP == NULL)
- handle_dm_notificationUPP =
- NewDMNotificationUPP (mac_handle_dm_notification);
-
- err = GetCurrentProcess (&psn);
- if (err == noErr)
- err = DMRegisterNotifyProc (handle_dm_notificationUPP, &psn);
-
- return err;
-}
-
-static void
-mac_get_screen_info (dpyinfo)
- struct mac_display_info *dpyinfo;
-{
-#ifdef MAC_OSX
- /* HasDepth returns true if it is possible to have a 32 bit display,
- but this may not be what is actually used. Mac OSX can do better. */
- dpyinfo->color_p = CGDisplaySamplesPerPixel (kCGDirectMainDisplay) > 1;
- dpyinfo->n_planes = CGDisplayBitsPerPixel (kCGDirectMainDisplay);
- {
- CGDisplayErr err;
- CGDisplayCount ndisps;
- CGDirectDisplayID *displays;
-
- err = CGGetActiveDisplayList (0, NULL, &ndisps);
- if (err == noErr)
- {
- displays = alloca (sizeof (CGDirectDisplayID) * ndisps);
- err = CGGetActiveDisplayList (ndisps, displays, &ndisps);
- }
- if (err == noErr)
- {
- CGRect bounds = CGRectZero;
-
- while (ndisps-- > 0)
- bounds = CGRectUnion (bounds, CGDisplayBounds (displays[ndisps]));
- dpyinfo->height = CGRectGetHeight (bounds);
- dpyinfo->width = CGRectGetWidth (bounds);
+ while (ndisps-- > 0)
+ bounds = CGRectUnion (bounds, CGDisplayBounds (displays[ndisps]));
+ dpyinfo->height = CGRectGetHeight (bounds);
+ dpyinfo->width = CGRectGetWidth (bounds);
}
else
{
dpyinfo->height = CGDisplayPixelsHigh (kCGDirectMainDisplay);
dpyinfo->width = CGDisplayPixelsWide (kCGDirectMainDisplay);
- }
- }
-#else /* !MAC_OSX */
- {
- GDHandle gdh = GetMainDevice ();
- Rect rect = (**gdh).gdRect;
-
- dpyinfo->color_p = TestDeviceAttribute (gdh, gdDevType);
- for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
- if (HasDepth (gdh, dpyinfo->n_planes, gdDevType, dpyinfo->color_p))
- break;
-
- for (gdh = DMGetFirstScreenDevice (dmOnlyActiveDisplays); gdh;
- gdh = DMGetNextScreenDevice (gdh, dmOnlyActiveDisplays))
- UnionRect (&rect, &(**gdh).gdRect, &rect);
-
- dpyinfo->height = rect.bottom - rect.top;
- dpyinfo->width = rect.right - rect.left;
- }
-#endif /* !MAC_OSX */
-}
-
-
-#if __profile__
-void
-profiler_exit_proc ()
-{
- ProfilerDump ("\pEmacs.prof");
- ProfilerTerm ();
-}
-#endif
-
-/* These few functions implement Emacs as a normal Mac application
- (almost): set up the heap and the Toolbox, handle necessary system
- events plus a few simple menu events. They also set up Emacs's
- access to functions defined in the rest of this file. Emacs uses
- function hooks to perform all its terminal I/O. A complete list of
- these functions appear in termhooks.h. For what they do, read the
- comments there and see also w32term.c and xterm.c. What's
- noticeably missing here is the event loop, which is normally
- present in most Mac application. After performing the necessary
- Mac initializations, main passes off control to emacs_main
- (corresponding to main in emacs.c). Emacs_main calls XTread_socket
- (defined further below) to read input. This is where
- WaitNextEvent/ReceiveNextEvent is called to process Mac events. */
-
-#ifdef MAC_OS8
-#undef main
-int
-main (void)
-{
-#if __profile__ /* is the profiler on? */
- if (ProfilerInit(collectDetailed, bestTimeBase, 5000, 200))
- exit(1);
-#endif
-
-#if __MWERKS__
- /* set creator and type for files created by MSL */
- _fcreator = MAC_EMACS_CREATOR_CODE;
- _ftype = 'TEXT';
-#endif
-
- do_init_managers ();
-
- do_get_menus ();
-
-#ifndef USE_LSB_TAG
- do_check_ram_size ();
-#endif
-
- init_emacs_passwd_dir ();
-
- init_environ ();
-
- init_coercion_handler ();
-
- initialize_applescript ();
-
- init_apple_event_handler ();
-
- init_dm_notification_handler ();
-
- {
- char **argv;
- int argc = 0;
-
- /* set up argv array from STR# resource */
- get_string_list (&argv, ARGV_STRING_LIST_ID);
- while (argv[argc])
- argc++;
-
- /* free up AppleScript resources on exit */
- atexit (terminate_applescript);
-
-#if __profile__ /* is the profiler on? */
- atexit (profiler_exit_proc);
-#endif
-
- /* 3rd param "envp" never used in emacs_main */
- (void) emacs_main (argc, argv, 0);
- }
-
- /* Never reached - real exit in Fkill_emacs */
- return 0;
-}
-#endif
-
-#if !USE_CARBON_EVENTS
-static RgnHandle mouse_region = NULL;
-
-Boolean
-mac_wait_next_event (er, sleep_time, dequeue)
- EventRecord *er;
- UInt32 sleep_time;
- Boolean dequeue;
-{
- static EventRecord er_buf = {nullEvent};
- UInt32 target_tick, current_tick;
- EventMask event_mask;
-
- if (mouse_region == NULL)
- mouse_region = NewRgn ();
-
- event_mask = everyEvent;
- if (!mac_ready_for_apple_events)
- event_mask -= highLevelEventMask;
-
- current_tick = TickCount ();
- target_tick = current_tick + sleep_time;
-
- if (er_buf.what == nullEvent)
- while (!WaitNextEvent (event_mask, &er_buf,
- target_tick - current_tick, mouse_region))
- {
- current_tick = TickCount ();
- if (target_tick <= current_tick)
- return false;
- }
-
- *er = er_buf;
- if (dequeue)
- er_buf.what = nullEvent;
- return true;
-}
-#endif /* not USE_CARBON_EVENTS */
-
-#if TARGET_API_MAC_CARBON
-OSStatus
-mac_post_mouse_moved_event ()
-{
- EventRef event = NULL;
- OSStatus err;
-
- err = CreateEvent (NULL, kEventClassMouse, kEventMouseMoved, 0,
- kEventAttributeNone, &event);
- if (err == noErr)
- {
- Point mouse_pos;
-
- GetGlobalMouse (&mouse_pos);
- err = SetEventParameter (event, kEventParamMouseLocation, typeQDPoint,
- sizeof (Point), &mouse_pos);
- }
- if (err == noErr)
- {
- UInt32 modifiers = GetCurrentKeyModifiers ();
-
- err = SetEventParameter (event, kEventParamKeyModifiers, typeUInt32,
- sizeof (UInt32), &modifiers);
- }
- if (err == noErr)
- err = PostEventToQueue (GetCurrentEventQueue (), event,
- kEventPriorityStandard);
- if (event)
- ReleaseEvent (event);
-
- return err;
-}
-
-static void
-mac_set_unicode_keystroke_event (code, buf)
- UniChar code;
- struct input_event *buf;
-{
- int charset_id, c1, c2;
-
- if (code < 0x80)
- {
- buf->kind = ASCII_KEYSTROKE_EVENT;
- buf->code = code;
- }
- else if (code < 0x100)
- {
- if (code < 0xA0)
- charset_id = CHARSET_8_BIT_CONTROL;
- else
- charset_id = charset_latin_iso8859_1;
- buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
- buf->code = MAKE_CHAR (charset_id, code, 0);
- }
- else
- {
- if (code < 0x2500)
- charset_id = charset_mule_unicode_0100_24ff,
- code -= 0x100;
- else if (code < 0x33FF)
- charset_id = charset_mule_unicode_2500_33ff,
- code -= 0x2500;
- else if (code >= 0xE000)
- charset_id = charset_mule_unicode_e000_ffff,
- code -= 0xE000;
- c1 = (code / 96) + 32, c2 = (code % 96) + 32;
- buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
- buf->code = MAKE_CHAR (charset_id, c1, c2);
- }
-}
-#endif
-
-/* Emacs calls this whenever it wants to read an input event from the
- user. */
-int
-XTread_socket (sd, expected, hold_quit)
- int sd, expected;
- struct input_event *hold_quit;
-{
- struct input_event inev;
- int count = 0;
-#if USE_CARBON_EVENTS
- EventRef eventRef;
- EventTargetRef toolbox_dispatcher;
-#endif
- EventRecord er;
- struct mac_display_info *dpyinfo = &one_mac_display_info;
-
- if (interrupt_input_blocked)
- {
- interrupt_input_pending = 1;
- return -1;
- }
-
- interrupt_input_pending = 0;
- BLOCK_INPUT;
-
- /* So people can tell when we have read the available input. */
- input_signal_count++;
-
- ++handling_signal;
-
-#if USE_CARBON_EVENTS
- toolbox_dispatcher = GetEventDispatcherTarget ();
-
- while (
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (NULL),
-#endif
- !ReceiveNextEvent (0, NULL, kEventDurationNoWait,
- kEventRemoveFromQueue, &eventRef))
-#else /* !USE_CARBON_EVENTS */
- while (mac_wait_next_event (&er, 0, true))
-#endif /* !USE_CARBON_EVENTS */
- {
- int do_help = 0;
- struct frame *f;
- unsigned long timestamp;
-
- EVENT_INIT (inev);
- inev.kind = NO_EVENT;
- inev.arg = Qnil;
-
-#if USE_CARBON_EVENTS
- timestamp = GetEventTime (eventRef) / kEventDurationMillisecond;
-#else
- timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
-#endif
-
-#if USE_CARBON_EVENTS
- /* Handle new events */
- if (!mac_convert_event_ref (eventRef, &er))
- {
- /* There used to be a handler for the kEventMouseWheelMoved
- event here. But as of Mac OS X 10.4, this kind of event
- is not directly posted to the main event queue by
- two-finger scrolling on the trackpad. Instead, some
- private event is posted and it is converted to a wheel
- event by the default handler for the application target.
- The converted one can be received by a Carbon event
- handler installed on a window target. */
- read_socket_inev = &inev;
- SendEventToEventTarget (eventRef, toolbox_dispatcher);
- read_socket_inev = NULL;
- }
- else
-#endif /* USE_CARBON_EVENTS */
- switch (er.what)
- {
- case mouseDown:
- case mouseUp:
- {
- WindowPtr window_ptr;
- ControlPartCode part_code;
- int tool_bar_p = 0;
-
-#if USE_CARBON_EVENTS
- /* This is needed to send mouse events like aqua window
- buttons to the correct handler. */
- if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
- != eventNotHandledErr)
- break;
-#endif
- last_mouse_glyph_frame = 0;
-
- if (dpyinfo->grabbed && last_mouse_frame
- && FRAME_LIVE_P (last_mouse_frame))
- {
- window_ptr = FRAME_MAC_WINDOW (last_mouse_frame);
- part_code = inContent;
- }
- else
- {
- part_code = FindWindow (er.where, &window_ptr);
- if (tip_window && window_ptr == tip_window)
- {
- HideWindow (tip_window);
- part_code = FindWindow (er.where, &window_ptr);
- }
- }
-
- if (er.what != mouseDown &&
- (part_code != inContent || dpyinfo->grabbed == 0))
- break;
-
- switch (part_code)
- {
- case inMenuBar:
- f = mac_focus_frame (dpyinfo);
- saved_menu_event_location = er.where;
- inev.kind = MENU_BAR_ACTIVATE_EVENT;
- XSETFRAME (inev.frame_or_window, f);
- break;
-
- case inContent:
- if (
-#if TARGET_API_MAC_CARBON
- FrontNonFloatingWindow ()
-#else
- FrontWindow ()
-#endif
- != window_ptr
- || (mac_window_to_frame (window_ptr)
- != dpyinfo->x_focus_frame))
- SelectWindow (window_ptr);
- else
- {
- ControlPartCode control_part_code;
- ControlHandle ch;
- Point mouse_loc = er.where;
-#ifdef MAC_OSX
- ControlKind control_kind;
-#endif
-
- f = mac_window_to_frame (window_ptr);
- /* convert to local coordinates of new window */
- SetPortWindowPort (window_ptr);
-
- GlobalToLocal (&mouse_loc);
-#if TARGET_API_MAC_CARBON
- ch = FindControlUnderMouse (mouse_loc, window_ptr,
- &control_part_code);
-#ifdef MAC_OSX
- if (ch)
- GetControlKind (ch, &control_kind);
-#endif
-#else
- control_part_code = FindControl (mouse_loc, window_ptr,
- &ch);
-#endif
-
-#if USE_CARBON_EVENTS
- inev.code = mac_get_mouse_btn (eventRef);
- inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
- inev.code = mac_get_emulated_btn (er.modifiers);
- inev.modifiers = mac_to_emacs_modifiers (er.modifiers, 0);
-#endif
- XSETINT (inev.x, mouse_loc.h);
- XSETINT (inev.y, mouse_loc.v);
-
- if ((dpyinfo->grabbed && tracked_scroll_bar)
- || (ch != 0
-#ifndef USE_TOOLKIT_SCROLL_BARS
- /* control_part_code becomes kControlNoPart if
- a progress indicator is clicked. */
- && control_part_code != kControlNoPart
-#else /* USE_TOOLKIT_SCROLL_BARS */
-#ifdef MAC_OSX
- && control_kind.kind == kControlKindScrollBar
-#endif /* MAC_OSX */
-#endif /* USE_TOOLKIT_SCROLL_BARS */
- ))
- {
- struct scroll_bar *bar;
-
- if (dpyinfo->grabbed && tracked_scroll_bar)
- {
- bar = tracked_scroll_bar;
-#ifndef USE_TOOLKIT_SCROLL_BARS
- control_part_code = kControlIndicatorPart;
-#endif
- }
- else
- bar = (struct scroll_bar *) GetControlReference (ch);
-#ifdef USE_TOOLKIT_SCROLL_BARS
- /* Make the "Ctrl-Mouse-2 splits window" work
- for toolkit scroll bars. */
- if (inev.modifiers & ctrl_modifier)
- x_scroll_bar_handle_click (bar, control_part_code,
- &er, &inev);
- else if (er.what == mouseDown)
- x_scroll_bar_handle_press (bar, control_part_code,
- mouse_loc, &inev);
- else
- x_scroll_bar_handle_release (bar, &inev);
-#else /* not USE_TOOLKIT_SCROLL_BARS */
- x_scroll_bar_handle_click (bar, control_part_code,
- &er, &inev);
- if (er.what == mouseDown
- && control_part_code == kControlIndicatorPart)
- tracked_scroll_bar = bar;
- else
- tracked_scroll_bar = NULL;
-#endif /* not USE_TOOLKIT_SCROLL_BARS */
- }
- else
- {
- Lisp_Object window;
- int x = mouse_loc.h;
- int y = mouse_loc.v;
-
- window = window_from_coordinates (f, x, y, 0, 0, 0, 1);
- if (EQ (window, f->tool_bar_window))
- {
- if (er.what == mouseDown)
- handle_tool_bar_click (f, x, y, 1, 0);
- else
- handle_tool_bar_click (f, x, y, 0,
- inev.modifiers);
- tool_bar_p = 1;
- }
- else
- {
- XSETFRAME (inev.frame_or_window, f);
- inev.kind = MOUSE_CLICK_EVENT;
- }
- }
-
- if (er.what == mouseDown)
- {
- dpyinfo->grabbed |= (1 << inev.code);
- last_mouse_frame = f;
-
- if (!tool_bar_p)
- last_tool_bar_item = -1;
- }
- else
- {
- if ((dpyinfo->grabbed & (1 << inev.code)) == 0)
- /* If a button is released though it was not
- previously pressed, that would be because
- of multi-button emulation. */
- dpyinfo->grabbed = 0;
- else
- dpyinfo->grabbed &= ~(1 << inev.code);
- }
-
- /* Ignore any mouse motion that happened before
- this event; any subsequent mouse-movement Emacs
- events should reflect only motion after the
- ButtonPress. */
- if (f != 0)
- f->mouse_moved = 0;
-
-#ifdef USE_TOOLKIT_SCROLL_BARS
- if (inev.kind == MOUSE_CLICK_EVENT
- || (inev.kind == SCROLL_BAR_CLICK_EVENT
- && (inev.modifiers & ctrl_modifier)))
-#endif
- switch (er.what)
- {
- case mouseDown:
- inev.modifiers |= down_modifier;
- break;
- case mouseUp:
- inev.modifiers |= up_modifier;
- break;
- }
- }
- break;
-
- case inDrag:
-#if TARGET_API_MAC_CARBON
- case inProxyIcon:
- if (IsWindowPathSelectClick (window_ptr, &er))
- {
- WindowPathSelect (window_ptr, NULL, NULL);
- break;
- }
- if (part_code == inProxyIcon
- && (TrackWindowProxyDrag (window_ptr, er.where)
- != errUserWantsToDragWindow))
- break;
- DragWindow (window_ptr, er.where, NULL);
-#else /* not TARGET_API_MAC_CARBON */
- DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
-#endif /* not TARGET_API_MAC_CARBON */
- /* Update the frame parameters. */
-#if !USE_CARBON_EVENTS
- {
- struct frame *f = mac_window_to_frame (window_ptr);
-
- if (f && !f->async_iconified)
- mac_handle_origin_change (f);
- }
-#endif
- break;
-
- case inGoAway:
- if (TrackGoAway (window_ptr, er.where))
- {
- inev.kind = DELETE_WINDOW_EVENT;
- XSETFRAME (inev.frame_or_window,
- mac_window_to_frame (window_ptr));
- }
- break;
-
- /* window resize handling added --ben */
- case inGrow:
- do_grow_window (window_ptr, &er);
- break;
-
- /* window zoom handling added --ben */
- case inZoomIn:
- case inZoomOut:
- if (TrackBox (window_ptr, er.where, part_code))
- do_zoom_window (window_ptr, part_code);
- break;
-
- default:
- break;
- }
- }
- break;
-
- case updateEvt:
-#if USE_CARBON_EVENTS
- if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
- != eventNotHandledErr)
- break;
-#else
- do_window_update ((WindowPtr) er.message);
-#endif
- break;
-
- case osEvt:
-#if USE_CARBON_EVENTS
- if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
- != eventNotHandledErr)
- break;
-#endif
- switch ((er.message >> 24) & 0x000000FF)
- {
- case suspendResumeMessage:
-#if USE_MAC_TSM
- if (er.message & resumeFlag)
- mac_tsm_resume ();
- else
- mac_tsm_suspend ();
-#endif
- break;
-
- case mouseMovedMessage:
-#if !USE_CARBON_EVENTS
- SetRectRgn (mouse_region, er.where.h, er.where.v,
- er.where.h + 1, er.where.v + 1);
-#endif
- previous_help_echo_string = help_echo_string;
- help_echo_string = Qnil;
-
- if (dpyinfo->grabbed && last_mouse_frame
- && FRAME_LIVE_P (last_mouse_frame))
- f = last_mouse_frame;
- else
- f = dpyinfo->x_focus_frame;
-
- if (dpyinfo->mouse_face_hidden)
- {
- dpyinfo->mouse_face_hidden = 0;
- clear_mouse_face (dpyinfo);
- }
-
- if (f)
- {
- WindowPtr wp = FRAME_MAC_WINDOW (f);
- Point mouse_pos = er.where;
-
- SetPortWindowPort (wp);
-
- GlobalToLocal (&mouse_pos);
-
- if (dpyinfo->grabbed && tracked_scroll_bar)
-#ifdef USE_TOOLKIT_SCROLL_BARS
- x_scroll_bar_handle_drag (wp, tracked_scroll_bar,
- mouse_pos, &inev);
-#else /* not USE_TOOLKIT_SCROLL_BARS */
- x_scroll_bar_note_movement (tracked_scroll_bar,
- mouse_pos.v
- - XINT (tracked_scroll_bar->top),
- er.when * (1000 / 60));
-#endif /* not USE_TOOLKIT_SCROLL_BARS */
- else
- {
- /* Generate SELECT_WINDOW_EVENTs when needed. */
- if (!NILP (Vmouse_autoselect_window))
- {
- Lisp_Object window;
-
- window = window_from_coordinates (f,
- mouse_pos.h,
- mouse_pos.v,
- 0, 0, 0, 0);
-
- /* Window will be selected only when it is
- not selected now and last mouse movement
- event was not in it. Minibuffer window
- will be selected only when it is active. */
- if (WINDOWP (window)
- && !EQ (window, last_window)
- && !EQ (window, selected_window)
- /* For click-to-focus window managers
- create event iff we don't leave the
- selected frame. */
- && (focus_follows_mouse
- || (EQ (XWINDOW (window)->frame,
- XWINDOW (selected_window)->frame))))
- {
- inev.kind = SELECT_WINDOW_EVENT;
- inev.frame_or_window = window;
- }
-
- last_window=window;
- }
- if (!note_mouse_movement (f, &mouse_pos))
- help_echo_string = previous_help_echo_string;
- }
- }
-
- /* If the contents of the global variable
- help_echo_string has changed, generate a
- HELP_EVENT. */
- if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
- do_help = 1;
- break;
- }
- break;
-
- case activateEvt:
- {
- WindowPtr window_ptr = (WindowPtr) er.message;
-
-#if USE_CARBON_EVENTS
- if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
- != eventNotHandledErr)
- break;
-#endif
- if (window_ptr == tip_window)
- {
- HideWindow (tip_window);
- break;
- }
+ }
+ }
+#else /* !MAC_OSX */
+ {
+ GDHandle gdh = GetMainDevice ();
+ Rect rect = (**gdh).gdRect;
- if (!is_emacs_window (window_ptr))
- break;
+ dpyinfo->color_p = TestDeviceAttribute (gdh, gdDevType);
+ for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
+ if (HasDepth (gdh, dpyinfo->n_planes, gdDevType, dpyinfo->color_p))
+ break;
- if ((er.modifiers & activeFlag) != 0)
- {
- /* A window has been activated */
- Point mouse_loc = er.where;
+ for (gdh = DMGetFirstScreenDevice (dmOnlyActiveDisplays); gdh;
+ gdh = DMGetNextScreenDevice (gdh, dmOnlyActiveDisplays))
+ UnionRect (&rect, &(**gdh).gdRect, &rect);
- x_detect_focus_change (dpyinfo, &er, &inev);
+ dpyinfo->height = rect.bottom - rect.top;
+ dpyinfo->width = rect.right - rect.left;
+ }
+#endif /* !MAC_OSX */
+}
- SetPortWindowPort (window_ptr);
- GlobalToLocal (&mouse_loc);
- /* Window-activated event counts as mouse movement,
- so update things that depend on mouse position. */
- note_mouse_movement (mac_window_to_frame (window_ptr),
- &mouse_loc);
- }
- else
- {
- /* A window has been deactivated */
-#ifdef USE_TOOLKIT_SCROLL_BARS
- if (dpyinfo->grabbed && tracked_scroll_bar)
- {
- struct input_event event;
-
- EVENT_INIT (event);
- event.kind = NO_EVENT;
- x_scroll_bar_handle_release (tracked_scroll_bar, &event);
- if (event.kind != NO_EVENT)
- {
- event.timestamp = timestamp;
- kbd_buffer_store_event_hold (&event, hold_quit);
- count++;
- }
- }
-#endif
- dpyinfo->grabbed = 0;
+\f
+/***********************************************************************
+ Initialization (Mac OS Classic)
+ ***********************************************************************/
- x_detect_focus_change (dpyinfo, &er, &inev);
+#ifdef MAC_OS8
+extern void init_emacs_passwd_dir ();
+extern int emacs_main (int, char **, char **);
- f = mac_window_to_frame (window_ptr);
- if (f == dpyinfo->mouse_face_mouse_frame)
- {
- /* If we move outside the frame, then we're
- certainly no longer on any text in the
- frame. */
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_mouse_frame = 0;
- }
+extern void initialize_applescript();
+extern void terminate_applescript();
- /* Generate a nil HELP_EVENT to cancel a help-echo.
- Do it only if there's something to cancel.
- Otherwise, the startup message is cleared when the
- mouse leaves the frame. */
- if (any_help_event_p)
- do_help = -1;
- }
- }
- break;
+static void
+do_get_menus (void)
+{
+ Handle menubar_handle;
+ MenuRef menu;
- case keyDown:
- case keyUp:
- case autoKey:
- {
- int keycode = (er.message & keyCodeMask) >> 8;
- static SInt16 last_key_script = -1;
- SInt16 current_key_script;
- UInt32 modifiers = er.modifiers, mapped_modifiers;
-
-#if USE_CARBON_EVENTS && defined (MAC_OSX)
- GetEventParameter (eventRef, kEventParamKeyModifiers,
- typeUInt32, NULL,
- sizeof (UInt32), NULL, &modifiers);
-#endif
- mapped_modifiers = mac_mapped_modifiers (modifiers, keycode);
-
-#if USE_CARBON_EVENTS && (defined (MAC_OSX) || USE_MAC_TSM)
- /* When using Carbon Events, we need to pass raw keyboard
- events to the TSM ourselves. If TSM handles it, it
- will pass back noErr, otherwise it will pass back
- "eventNotHandledErr" and we can process it
- normally. */
- if (!(mapped_modifiers
- & ~(mac_pass_command_to_system ? cmdKey : 0)
- & ~(mac_pass_control_to_system ? controlKey : 0)))
- {
- OSStatus err;
+ menubar_handle = GetNewMBar (128);
+ if(menubar_handle == NULL)
+ abort ();
+ SetMenuBar (menubar_handle);
+ DrawMenuBar ();
- read_socket_inev = &inev;
- err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
- read_socket_inev = NULL;
- if (err != eventNotHandledErr)
- break;
- }
+#if !TARGET_API_MAC_CARBON
+ menu = GetMenuRef (M_APPLE);
+ if (menu != NULL)
+ AppendResMenu (menu, 'DRVR');
+ else
+ abort ();
#endif
- if (er.what == keyUp)
- break;
+}
- ObscureCursor ();
+static void
+do_init_managers (void)
+{
+#if !TARGET_API_MAC_CARBON
+ InitGraf (&qd.thePort);
+ InitFonts ();
+ FlushEvents (everyEvent, 0);
+ InitWindows ();
+ InitMenus ();
+ TEInit ();
+ InitDialogs (NULL);
+#endif /* !TARGET_API_MAC_CARBON */
+ InitCursor ();
- f = mac_focus_frame (dpyinfo);
+#if !TARGET_API_MAC_CARBON
+ /* set up some extra stack space for use by emacs */
+ SetApplLimit ((Ptr) ((long) GetApplLimit () - EXTRA_STACK_ALLOC));
- if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
- && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
- {
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_hidden = 1;
- }
+ /* MaxApplZone must be called for AppleScript to execute more
+ complicated scripts */
+ MaxApplZone ();
+ MoreMasters ();
+#endif /* !TARGET_API_MAC_CARBON */
+}
- current_key_script = GetScriptManagerVariable (smKeyScript);
- if (last_key_script != current_key_script)
- {
- struct input_event event;
-
- EVENT_INIT (event);
- event.kind = LANGUAGE_CHANGE_EVENT;
- event.arg = Qnil;
- event.code = current_key_script;
- event.timestamp = timestamp;
- kbd_buffer_store_event (&event);
- count++;
- last_key_script = current_key_script;
- }
+static void
+do_check_ram_size (void)
+{
+ SInt32 physical_ram_size, logical_ram_size;
-#if USE_MAC_TSM
- if (inev.kind != NO_EVENT)
- break;
-#endif
+ if (Gestalt (gestaltPhysicalRAMSize, &physical_ram_size) != noErr
+ || Gestalt (gestaltLogicalRAMSize, &logical_ram_size) != noErr
+ || physical_ram_size > (1 << VALBITS)
+ || logical_ram_size > (1 << VALBITS))
+ {
+ StopAlert (RAM_TOO_LARGE_ALERT_ID, NULL);
+ exit (1);
+ }
+}
-#ifdef MAC_OSX
- if (mapped_modifiers & kEventKeyModifierFnMask
- && keycode <= 0x7f
- && fn_keycode_to_keycode_table[keycode])
- keycode = fn_keycode_to_keycode_table[keycode];
+#if __profile__
+void
+profiler_exit_proc ()
+{
+ ProfilerDump ("\pEmacs.prof");
+ ProfilerTerm ();
+}
#endif
- if (keycode <= 0x7f && keycode_to_xkeysym_table [keycode])
- {
- inev.kind = NON_ASCII_KEYSTROKE_EVENT;
- inev.code = 0xff00 | keycode_to_xkeysym_table [keycode];
- }
- else if (mapped_modifiers)
- {
- /* translate the keycode back to determine the
- original key */
-#ifdef MAC_OSX
- UCKeyboardLayout *uchr_ptr = NULL;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- OSStatus err;
- KeyboardLayoutRef layout;
- err = KLGetCurrentKeyboardLayout (&layout);
- if (err == noErr)
- KLGetKeyboardLayoutProperty (layout, kKLuchrData,
- (const void **) &uchr_ptr);
-#else
- static SInt16 last_key_layout_id = 0;
- static Handle uchr_handle = (Handle)-1;
- SInt16 current_key_layout_id =
- GetScriptVariable (current_key_script, smScriptKeys);
+/* These few functions implement Emacs as a normal Mac application
+ (almost): set up the heap and the Toolbox, handle necessary system
+ events plus a few simple menu events. They also set up Emacs's
+ access to functions defined in the rest of this file. Emacs uses
+ function hooks to perform all its terminal I/O. A complete list of
+ these functions appear in termhooks.h. For what they do, read the
+ comments there and see also w32term.c and xterm.c. What's
+ noticeably missing here is the event loop, which is normally
+ present in most Mac application. After performing the necessary
+ Mac initializations, main passes off control to emacs_main
+ (corresponding to main in emacs.c). Emacs_main calls XTread_socket
+ (defined further below) to read input. This is where
+ WaitNextEvent/ReceiveNextEvent is called to process Mac events. */
- if (uchr_handle == (Handle)-1
- || last_key_layout_id != current_key_layout_id)
- {
- uchr_handle = GetResource ('uchr', current_key_layout_id);
- last_key_layout_id = current_key_layout_id;
- }
- if (uchr_handle)
- uchr_ptr = (UCKeyboardLayout *)*uchr_handle;
+#undef main
+int
+main (void)
+{
+#if __profile__ /* is the profiler on? */
+ if (ProfilerInit(collectDetailed, bestTimeBase, 5000, 200))
+ exit(1);
#endif
- if (uchr_ptr)
- {
- OSStatus status;
- UInt16 key_action = er.what - keyDown;
- UInt32 modifier_key_state =
- (modifiers & ~mapped_modifiers) >> 8;
- UInt32 keyboard_type = LMGetKbdType ();
- SInt32 dead_key_state = 0;
- UniChar code;
- UniCharCount actual_length;
-
- status = UCKeyTranslate (uchr_ptr,
- keycode, key_action,
- modifier_key_state,
- keyboard_type,
- kUCKeyTranslateNoDeadKeysMask,
- &dead_key_state,
- 1, &actual_length, &code);
- if (status == noErr && actual_length == 1)
- mac_set_unicode_keystroke_event (code, &inev);
- }
-#endif /* MAC_OSX */
-
- if (inev.kind == NO_EVENT)
- {
- /* This code comes from Keyboard Resource,
- Appendix C of IM - Text. This is necessary
- since shift is ignored in KCHR table
- translation when option or command is pressed.
- It also does not translate correctly
- control-shift chars like C-% so mask off shift
- here also. */
- /* Mask off modifier keys that are mapped to some
- Emacs modifiers. */
- int new_modifiers = er.modifiers & ~mapped_modifiers;
- /* set high byte of keycode to modifier high byte*/
- int new_keycode = keycode | new_modifiers;
- Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
- unsigned long some_state = 0;
- UInt32 new_char_code;
-
- new_char_code = KeyTranslate (kchr_ptr, new_keycode,
- &some_state);
- if (new_char_code == 0)
- /* Seems like a dead key. Append up-stroke. */
- new_char_code = KeyTranslate (kchr_ptr,
- new_keycode | 0x80,
- &some_state);
- if (new_char_code)
- {
- inev.kind = ASCII_KEYSTROKE_EVENT;
- inev.code = new_char_code & 0xff;
- }
- }
- }
-
- if (inev.kind == NO_EVENT)
- {
- inev.kind = ASCII_KEYSTROKE_EVENT;
- inev.code = er.message & charCodeMask;
- }
-
- inev.modifiers = mac_to_emacs_modifiers (mapped_modifiers,
- modifiers);
- inev.modifiers |= (extra_keyboard_modifiers
- & (meta_modifier | alt_modifier
- | hyper_modifier | super_modifier));
- XSETFRAME (inev.frame_or_window, f);
-
-#if TARGET_API_MAC_CARBON
- if (inev.kind == ASCII_KEYSTROKE_EVENT
- && inev.code >= 0x80 && inev.modifiers)
- {
- OSStatus err;
- TextEncoding encoding = kTextEncodingMacRoman;
- TextToUnicodeInfo ttu_info;
-
- UpgradeScriptInfoToTextEncoding (current_key_script,
- kTextLanguageDontCare,
- kTextRegionDontCare,
- NULL, &encoding);
- err = CreateTextToUnicodeInfoByEncoding (encoding, &ttu_info);
- if (err == noErr)
- {
- UniChar code;
- Str255 pstr;
- ByteCount unicode_len;
-
- pstr[0] = 1;
- pstr[1] = inev.code;
- err = ConvertFromPStringToUnicode (ttu_info, pstr,
- sizeof (UniChar),
- &unicode_len, &code);
- if (err == noErr && unicode_len == sizeof (UniChar))
- mac_set_unicode_keystroke_event (code, &inev);
- DisposeTextToUnicodeInfo (&ttu_info);
- }
- }
+#if __MWERKS__
+ /* set creator and type for files created by MSL */
+ _fcreator = MAC_EMACS_CREATOR_CODE;
+ _ftype = 'TEXT';
#endif
- }
- break;
- case kHighLevelEvent:
- AEProcessAppleEvent (&er);
- break;
+ do_init_managers ();
- default:
- break;
- }
-#if USE_CARBON_EVENTS
- ReleaseEvent (eventRef);
-#endif
+ do_get_menus ();
- if (inev.kind != NO_EVENT)
- {
- inev.timestamp = timestamp;
- kbd_buffer_store_event_hold (&inev, hold_quit);
- count++;
- }
+#ifndef USE_LSB_TAG
+ do_check_ram_size ();
+#endif
- if (do_help
- && !(hold_quit && hold_quit->kind != NO_EVENT))
- {
- Lisp_Object frame;
+ init_emacs_passwd_dir ();
- if (f)
- XSETFRAME (frame, f);
- else
- frame = Qnil;
+ init_environ ();
- if (do_help > 0)
- {
- any_help_event_p = 1;
- gen_help_event (help_echo_string, frame, help_echo_window,
- help_echo_object, help_echo_pos);
- }
- else
- {
- help_echo_string = Qnil;
- gen_help_event (Qnil, frame, Qnil, Qnil, 0);
- }
- count++;
- }
+ init_coercion_handler ();
- }
+ initialize_applescript ();
- /* If the focus was just given to an autoraising frame,
- raise it now. */
- /* ??? This ought to be able to handle more than one such frame. */
- if (pending_autoraise_frame)
- {
- x_raise_frame (pending_autoraise_frame);
- pending_autoraise_frame = 0;
- }
+ init_apple_event_handler ();
- if (mac_screen_config_changed)
- {
- mac_get_screen_info (dpyinfo);
- mac_screen_config_changed = 0;
- }
+ init_dm_notification_handler ();
-#if !USE_CARBON_EVENTS
- /* Check which frames are still visible. We do this here because
- there doesn't seem to be any direct notification from the Window
- Manager that the visibility of a window has changed (at least,
- not in all cases). */
{
- Lisp_Object tail, frame;
+ char **argv;
+ int argc = 0;
- FOR_EACH_FRAME (tail, frame)
- {
- struct frame *f = XFRAME (frame);
+ /* set up argv array from STR# resource */
+ get_string_list (&argv, ARGV_STRING_LIST_ID);
+ while (argv[argc])
+ argc++;
- /* The tooltip has been drawn already. Avoid the
- SET_FRAME_GARBAGED in mac_handle_visibility_change. */
- if (EQ (frame, tip_frame))
- continue;
+ /* free up AppleScript resources on exit */
+ atexit (terminate_applescript);
- if (FRAME_MAC_P (f))
- mac_handle_visibility_change (f);
- }
- }
+#if __profile__ /* is the profiler on? */
+ atexit (profiler_exit_proc);
#endif
- --handling_signal;
- UNBLOCK_INPUT;
- return count;
-}
+ /* 3rd param "envp" never used in emacs_main */
+ (void) emacs_main (argc, argv, 0);
+ }
+ /* Never reached - real exit in Fkill_emacs */
+ return 0;
+}
/* Need to override CodeWarrior's input function so no conversion is
done on newlines Otherwise compiled functions in .elc files will be
}
#endif
-#ifdef MAC_OS8
void
make_mac_terminal_frame (struct frame *f)
{
if (!(FRAME_MAC_WINDOW (f) =
NewCWindow (NULL, &r, "\p", true, dBoxProc,
- (WindowPtr) -1, 1, (long) f->output_data.mac)))
+ (WindowRef) -1, 1, (long) f->output_data.mac)))
abort ();
/* so that update events can find this mac_output struct */
f->output_data.mac->mFP = f; /* point back to emacs frame */
Fcons (Fcons (Qbackground_color,
build_string ("white")), Qnil));
}
-#endif
+#endif /* MAC_OS8 */
\f
/***********************************************************************
}
\f
-static void
-init_menu_bar ()
-{
-#ifdef MAC_OSX
- OSStatus err;
- MenuRef menu;
- MenuItemIndex menu_index;
-
- err = GetIndMenuItemWithCommandID (NULL, kHICommandQuit, 1,
- &menu, &menu_index);
- if (err == noErr)
- SetMenuItemCommandKey (menu, menu_index, false, 0);
-#if USE_CARBON_EVENTS
- EnableMenuCommand (NULL, kHICommandPreferences);
- err = GetIndMenuItemWithCommandID (NULL, kHICommandPreferences, 1,
- &menu, &menu_index);
- if (err == noErr)
- {
- SetMenuItemCommandKey (menu, menu_index, false, 0);
- InsertMenuItemTextWithCFString (menu, NULL,
- 0, kMenuItemAttrSeparator, 0);
- InsertMenuItemTextWithCFString (menu, CFSTR ("About Emacs"),
- 0, 0, kHICommandAbout);
- }
-#endif /* USE_CARBON_EVENTS */
-#else /* !MAC_OSX */
-#if USE_CARBON_EVENTS
- SetMenuItemCommandID (GetMenuHandle (M_APPLE), I_ABOUT, kHICommandAbout);
-#endif
-#endif
-}
-
-#if USE_MAC_TSM
-static void
-init_tsm ()
-{
-#ifdef MAC_OSX
- static InterfaceTypeList types = {kUnicodeDocument};
-#else
- static InterfaceTypeList types = {kTextService};
-#endif
-
- NewTSMDocument (sizeof (types) / sizeof (types[0]), types,
- &tsm_document_id, 0);
-}
-#endif
-
/* Set up use of X before we make the first connection. */
extern frame_parm_handler mac_frame_parm_handlers[];
baud_rate = 19200;
last_tool_bar_item = -1;
- any_help_event_p = 0;
/* Try to use interrupt input; if we can't, then start polling. */
Fset_input_mode (Qt, Qnil, Qt, Qnil);
BLOCK_INPUT;
#if TARGET_API_MAC_CARBON
-
-#if USE_CARBON_EVENTS
#ifdef MAC_OSX
- init_service_handler ();
-#endif /* MAC_OSX */
-
- init_command_handler ();
-
- init_menu_bar ();
+ init_coercion_handler ();
-#if USE_MAC_TSM
- init_tsm ();
+ init_dm_notification_handler ();
#endif
-#endif /* USE_CARBON_EVENTS */
-
-#ifdef MAC_OSX
- init_coercion_handler ();
- init_apple_event_handler ();
+ install_application_handler ();
- init_dm_notification_handler ();
+ mac_toolbox_initialize ();
+#ifdef MAC_OSX
if (!inhibit_window_system)
{
static const ProcessSerialNumber psn = {0, kCurrentProcess};
Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier));
Fput (Qsuper, Qmodifier_value, make_number (super_modifier));
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
Qhi_command = intern ("hi-command"); staticpro (&Qhi_command);
#ifdef MAC_OSX
Qtoolbar_switch_mode = intern ("toolbar-switch-mode");
Qservice = intern ("service"); staticpro (&Qservice);
Qpaste = intern ("paste"); staticpro (&Qpaste);
Qperform = intern ("perform"); staticpro (&Qperform);
+
+ Qmouse_drag_overlay = intern ("mouse-drag-overlay");
+ staticpro (&Qmouse_drag_overlay);
#endif
#if USE_MAC_TSM
Qtext_input = intern ("text-input"); staticpro (&Qtext_input);
mouse-3 and the command-key will register for mouse-2. */);
Vmac_emulate_three_button_mouse = Qnil;
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
DEFVAR_BOOL ("mac-wheel-button-is-mouse-2", &mac_wheel_button_is_mouse_2,
doc: /* *Non-nil if the wheel button is mouse-2 and the right click mouse-3.
Otherwise, the right click will be treated as mouse-2 and the wheel
doc: /* Overlay used to display Mac TSM active input area. */);
Vmac_ts_active_input_overlay = Qnil;
+ DEFVAR_LISP ("mac-ts-active-input-buf", &Vmac_ts_active_input_buf,
+ doc: /* Byte sequence of the current Mac TSM active input area. */);
+ /* `empty_string' is not ready yet on Mac OS Classic. */
+ Vmac_ts_active_input_buf = build_string ("");
+
DEFVAR_LISP ("mac-ts-script-language-on-focus", &Vmac_ts_script_language_on_focus,
doc: /* *How to change Mac TSM script/language when a frame gets focus.
If the value is t, the input script and language are restored to those
#include "frame.h"
#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
+#define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
-#define RED_FROM_ULONG(color) ((color) >> 16)
+#define ALPHA_FROM_ULONG(color) ((color) >> 24)
+#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
#define BLUE_FROM_ULONG(color) ((color) & 0xff)
/* Hints for the size and the position of a window. */
XSizeHints *size_hints;
+#if USE_MAC_TOOLBAR
+ /* This variable records the gravity value of the window position if
+ the window has an external tool bar when it is created. The
+ position of the window is adjusted using this information when
+ the tool bar is first redisplayed. Once the tool bar is
+ redisplayed, it is set to 0 in order to avoid further
+ adjustment. */
+ int toolbar_win_gravity;
+#endif
+
#if USE_CG_DRAWING
/* Quartz 2D graphics context. */
CGContextRef cg_context;
/* The next and previous in the chain of scroll bars in this frame. */
Lisp_Object next, prev;
- /* The Mac control handle of this scroll bar. Since this is a
+ /* The Mac control reference of this scroll bar. Since this is a
pointer value, we store it split into two Lisp integers. */
- Lisp_Object control_handle_low, control_handle_high;
+ Lisp_Object control_ref_low, control_ref_high;
/* The position and size of the scroll bar in pixels, relative to the
frame. */
being dragged, this is Qnil. */
Lisp_Object dragging;
+#ifdef MAC_OSX
+ /* t if the background of the fringe that is adjacent to a scroll
+ bar is extended to the gap between the fringe and the bar. */
+ Lisp_Object fringe_extended_p;
+#endif
+
/* t if redraw needed in the next XTset_vertical_scroll_bar call. */
Lisp_Object redraw_needed_p;
/* Extract the Mac control handle of the scroll bar from a struct
scroll_bar. */
-#define SCROLL_BAR_CONTROL_HANDLE(ptr) \
- ((ControlHandle) SCROLL_BAR_PACK ((ptr)->control_handle_low, \
- (ptr)->control_handle_high))
+#define SCROLL_BAR_CONTROL_REF(ptr) \
+ ((ControlRef) SCROLL_BAR_PACK ((ptr)->control_ref_low, \
+ (ptr)->control_ref_high))
/* Store a Mac control handle in a struct scroll_bar. */
-#define SET_SCROLL_BAR_CONTROL_HANDLE(ptr, handle) \
- (SCROLL_BAR_UNPACK ((ptr)->control_handle_low, \
- (ptr)->control_handle_high, (unsigned long) (handle)))
+#define SET_SCROLL_BAR_CONTROL_REF(ptr, ref) \
+ (SCROLL_BAR_UNPACK ((ptr)->control_ref_low, \
+ (ptr)->control_ref_high, (unsigned long) (ref)))
/* Return the inside width of a vertical scroll bar, given the outside
width. */
#define MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH (11)
/* Size of hourglass controls */
-#define HOURGLASS_WIDTH (16)
-#define HOURGLASS_HEIGHT (16)
+#define HOURGLASS_WIDTH (15)
+#define HOURGLASS_HEIGHT (15)
/* Some constants that are used locally. */
/* Creator code for Emacs on Mac OS. */
};
#endif
+#if 0
+/* We can't determine the availability of these enumerators by
+ MAC_OS_X_VERSION_MAX_ALLOWED, because they are defined in
+ MacOSX10.3.9.sdk for Mac OS X 10.4, but not in Mac OS X 10.3. */
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1040
/* Gestalt selectors */
enum {
gestaltSystemVersionBugFix = 'sys3'
};
#endif
+#endif
#ifdef MAC_OSX
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1020
kEventParamWindowMouseLocation = 'wmou'
};
#endif
+
+/* kCGBitmapByteOrder32Host is defined in Universal SDK for 10.4 but
+ not in PPC SDK for 10.4.0. */
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 && !defined (kCGBitmapByteOrder32Host)
+#define kCGBitmapByteOrder32Host 0
#endif
+#endif /* MAC_OSX */
struct frame;
struct face;
extern void x_set_window_size P_ ((struct frame *, int, int, int));
extern void x_set_mouse_position P_ ((struct frame *, int, int));
extern void x_set_mouse_pixel_position P_ ((struct frame *, int, int));
+extern void x_raise_frame P_ ((struct frame *));
+extern void x_lower_frame P_ ((struct frame *));
extern void x_make_frame_visible P_ ((struct frame *));
extern void x_make_frame_invisible P_ ((struct frame *));
extern void x_iconify_frame P_ ((struct frame *));
extern void x_wm_set_size_hint P_ ((struct frame *, long, int));
extern void x_delete_display P_ ((struct x_display_info *));
extern void mac_initialize P_ ((void));
-extern Pixmap XCreatePixmap P_ ((Display *, WindowPtr, unsigned int,
+extern Pixmap XCreatePixmap P_ ((Display *, Window, unsigned int,
unsigned int, unsigned int));
-extern Pixmap XCreatePixmapFromBitmapData P_ ((Display *, WindowPtr, char *,
+extern Pixmap XCreatePixmapFromBitmapData P_ ((Display *, Window, char *,
unsigned int, unsigned int,
unsigned long, unsigned long,
unsigned int));
extern void XFreeGC P_ ((Display *, GC));
extern void XSetForeground P_ ((Display *, GC, unsigned long));
extern void XSetBackground P_ ((Display *, GC, unsigned long));
-extern void XSetWindowBackground P_ ((Display *, WindowPtr, unsigned long));
extern void XDrawLine P_ ((Display *, Pixmap, GC, int, int, int, int));
extern void mac_clear_area P_ ((struct frame *, int, int,
unsigned int, unsigned int));
extern void mac_unload_font P_ ((struct mac_display_info *, XFontStruct *));
-extern int mac_font_panel_visible_p P_ ((void));
-extern OSStatus mac_show_hide_font_panel P_ ((void));
-extern OSStatus mac_set_font_info_for_selection P_ ((struct frame *, int, int));
-extern OSStatus install_window_handler P_ ((WindowPtr));
-extern void remove_window_handler P_ ((WindowPtr));
extern OSStatus mac_post_mouse_moved_event P_ ((void));
-#if !TARGET_API_MAC_CARBON
-extern void do_apple_menu P_ ((SInt16));
-#endif
-#if USE_CG_DRAWING
-extern void mac_prepare_for_quickdraw P_ ((struct frame *));
-#endif
extern int mac_quit_char_key_p P_ ((UInt32, UInt32));
#define FONT_TYPE_FOR_UNIBYTE(font, ch) 0
#define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0
+#if USE_MAC_IMAGE_IO
+extern CGColorSpaceRef mac_cg_color_space_rgb;
+#endif
+
/* Defined in macselect.c */
extern void x_clear_frame_selections P_ ((struct frame *));
+EXFUN (Fx_selection_owner_p, 1);
/* Defined in macfns.c */
extern void mac_update_title_bar P_ ((struct frame *, int));
extern Lisp_Object x_get_focus_frame P_ ((struct frame *));
-/* Defined in macmenu.c */
-
-extern void x_activate_menubar P_ ((struct frame *));
-extern void free_frame_menubar P_ ((struct frame *));
-
/* Defined in mac.c. */
extern void mac_clear_font_name_table P_ ((void));
extern Lisp_Object mac_aedesc_to_lisp P_ ((const AEDesc *));
extern OSErr mac_ae_put_lisp P_ ((AEDescList *, UInt32, Lisp_Object));
#if TARGET_API_MAC_CARBON
-extern OSStatus create_apple_event_from_event_ref P_ ((EventRef, UInt32,
- const EventParamName *,
- const EventParamType *,
- AppleEvent *));
-extern OSErr create_apple_event_from_drag_ref P_ ((DragRef, UInt32,
- const FlavorType *,
- AppleEvent *));
+extern OSErr create_apple_event P_ ((AEEventClass, AEEventID, AppleEvent *));
+extern Lisp_Object mac_event_parameters_to_lisp P_ ((EventRef, UInt32,
+ const EventParamName *,
+ const EventParamType *));
extern CFStringRef cfstring_create_with_utf8_cstring P_ ((const char *));
extern CFStringRef cfstring_create_with_string P_ ((Lisp_Object));
extern Lisp_Object cfdata_to_lisp P_ ((CFDataRef));
extern XrmDatabase xrm_get_preference_database P_ ((const char *));
EXFUN (Fmac_get_preference, 4);
+/* Defined in mactoolbox.c. */
+
+extern void mac_alert_sound_play P_ ((void));
+extern OSStatus install_application_handler P_ ((void));
+extern void mac_get_window_bounds P_ ((struct frame *, Rect *, Rect *));
+extern Rect *mac_get_frame_bounds P_ ((struct frame *, Rect *));
+extern void mac_get_frame_mouse P_ ((struct frame *, Point *));
+extern void mac_convert_frame_point_to_global P_ ((struct frame *, int *,
+ int *));
+#if TARGET_API_MAC_CARBON
+extern void mac_update_proxy_icon P_ ((struct frame *));
+#endif
+extern void mac_set_frame_window_background P_ ((struct frame *,
+ unsigned long));
+extern void mac_update_begin P_ ((struct frame *));
+extern void mac_update_end P_ ((struct frame *));
+extern void mac_frame_up_to_date P_ ((struct frame *));
+extern void x_flush P_ ((struct frame *));
+extern void mac_create_frame_window P_ ((struct frame *, int));
+extern void mac_dispose_frame_window P_ ((struct frame *));
+#if USE_CG_DRAWING
+extern CGContextRef mac_begin_cg_clip P_ ((struct frame *, GC));
+extern void mac_end_cg_clip P_ ((struct frame *));
+#endif
+extern void mac_begin_clip P_ ((struct frame *, GC));
+extern void mac_end_clip P_ ((struct frame *, GC));
+extern void mac_create_scroll_bar P_ ((struct scroll_bar *, const Rect *,
+ Boolean));
+extern void mac_dispose_scroll_bar P_ ((struct scroll_bar *));
+extern void mac_set_scroll_bar_bounds P_ ((struct scroll_bar *, const Rect *));
+extern void mac_redraw_scroll_bar P_ ((struct scroll_bar *));
+#ifdef USE_TOOLKIT_SCROLL_BARS
+extern void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *,
+ int, int, int));
+#else
+extern void x_scroll_bar_set_handle P_ ((scroll_bar *, int, int, int));
+#endif
+#if USE_MAC_FONT_PANEL
+extern int mac_font_panel_visible_p P_ ((void));
+extern OSStatus mac_show_hide_font_panel P_ ((void));
+extern OSStatus mac_set_font_info_for_selection P_ ((struct frame *, int, int));
+#endif
+#ifdef MAC_OSX
+extern Boolean mac_run_loop_run_once P_ ((EventTimeout));
+#endif
+#if USE_MAC_TOOLBAR
+extern void update_frame_tool_bar P_ ((FRAME_PTR f));
+extern void free_frame_tool_bar P_ ((FRAME_PTR f));
+#endif
+#if TARGET_API_MAC_CARBON
+extern void mac_show_hourglass P_ ((struct frame *));
+extern void mac_hide_hourglass P_ ((struct frame *));
+extern void mac_reposition_hourglass P_ ((struct frame *));
+extern Lisp_Object mac_file_dialog P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
+ Lisp_Object, Lisp_Object));
+#endif
+extern void x_activate_menubar P_ ((struct frame *));
+extern void free_frame_menubar P_ ((struct frame *));
+extern void mac_fill_menubar P_ ((widget_value *, int));
+extern void create_and_show_popup_menu P_ ((FRAME_PTR, widget_value *,
+ int, int, int));
+#if TARGET_API_MAC_CARBON
+extern void create_and_show_dialog P_ ((FRAME_PTR, widget_value *));
+#else
+extern int mac_dialog P_ ((widget_value *));
+#endif
+extern OSStatus mac_get_selection_from_symbol P_ ((Lisp_Object, int,
+ Selection *));
+extern int mac_valid_selection_target_p P_ ((Lisp_Object));
+extern OSStatus mac_clear_selection P_ ((Selection *));
+extern Lisp_Object mac_get_selection_ownership_info P_ ((Selection));
+extern int mac_valid_selection_value_p P_ ((Lisp_Object, Lisp_Object));
+extern OSStatus mac_put_selection_value P_ ((Selection, Lisp_Object,
+ Lisp_Object));
+extern int mac_selection_has_target_p P_ ((Selection, Lisp_Object));
+extern Lisp_Object mac_get_selection_value P_ ((Selection, Lisp_Object));
+extern Lisp_Object mac_get_selection_target_list P_ ((Selection));
+#if TARGET_API_MAC_CARBON
+extern Lisp_Object mac_dnd_default_known_types P_ ((void));
+#endif
+
/* arch-tag: 6b4ca125-5bef-476d-8ee8-31ed808b7e79
(do not change this comment) */
--- /dev/null
+/* Functions for GUI implemented with (HI)Toolbox on the Mac OS.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004,
+ 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "lisp.h"
+#include "blockinput.h"
+
+#include "macterm.h"
+
+#if !TARGET_API_MAC_CARBON
+#include <Quickdraw.h>
+#include <ToolUtils.h>
+#include <Sound.h>
+#include <Events.h>
+#include <Script.h>
+#include <Resources.h>
+#include <Fonts.h>
+#include <TextUtils.h>
+#include <LowMem.h>
+#include <Controls.h>
+#include <Windows.h>
+#include <Displays.h>
+#if defined (__MRC__) || (__MSL__ >= 0x6000)
+#include <ControlDefinitions.h>
+#endif
+
+#if __profile__
+#include <profiler.h>
+#endif
+#endif /* not TARGET_API_MAC_CARBON */
+
+#include "charset.h"
+#include "coding.h"
+#include "frame.h"
+#include "dispextern.h"
+#include "fontset.h"
+#include "termhooks.h"
+#include "buffer.h"
+#include "window.h"
+#include "keyboard.h"
+
+#include <sys/param.h>
+
+#ifndef MAC_OSX
+#include <alloca.h>
+#endif
+
+\f
+/************************************************************************
+ General
+ ************************************************************************/
+
+/* The difference in pixels between the top left corner of the
+ Emacs window (including possible window manager decorations)
+ and FRAME_MAC_WINDOW (f). */
+#define FRAME_OUTER_TO_INNER_DIFF_X(f) ((f)->x_pixels_diff)
+#define FRAME_OUTER_TO_INNER_DIFF_Y(f) ((f)->y_pixels_diff)
+
+#define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
+
+void
+mac_alert_sound_play ()
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ AlertSoundPlay ();
+#else
+ SysBeep (1);
+#endif
+}
+
+\f
+/************************************************************************
+ Application
+ ************************************************************************/
+
+extern struct frame *mac_focus_frame P_ ((struct mac_display_info *));
+extern void do_keystroke P_ ((EventKind, unsigned char, UInt32, UInt32,
+ unsigned long, struct input_event *));
+extern UInt32 mac_mapped_modifiers P_ ((UInt32, UInt32));
+#if TARGET_API_MAC_CARBON
+extern int mac_to_emacs_modifiers P_ ((UInt32, UInt32));
+#else
+extern int mac_to_emacs_modifiers P_ ((EventModifiers, EventModifiers));
+#endif
+
+#if TARGET_API_MAC_CARBON
+/* Points to the variable `inev' in the function XTread_socket. It is
+ used for passing an input event to the function back from
+ Carbon/Apple event handlers. */
+static struct input_event *read_socket_inev = NULL;
+
+extern const unsigned char keycode_to_xkeysym_table[];
+extern EMACS_INT extra_keyboard_modifiers;
+
+extern Lisp_Object Qhi_command;
+#if USE_MAC_TSM
+static TSMDocumentID tsm_document_id;
+extern Lisp_Object Qtext_input;
+extern Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
+extern Lisp_Object Vmac_ts_active_input_overlay, Vmac_ts_active_input_buf;
+extern Lisp_Object Qbefore_string;
+#endif
+
+static int mac_event_to_emacs_modifiers P_ ((EventRef));
+static OSStatus install_menu_target_item_handler P_ ((void));
+#ifdef MAC_OSX
+static OSStatus install_service_handler P_ ((void));
+#endif
+
+extern OSStatus mac_store_event_ref_as_apple_event P_ ((AEEventClass, AEEventID,
+ Lisp_Object,
+ Lisp_Object,
+ EventRef, UInt32,
+ const EventParamName *,
+ const EventParamType *));
+extern int fast_find_position P_ ((struct window *, int, int *, int *,
+ int *, int *, Lisp_Object));
+extern struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
+ int *, int *, int *, int *, int *));
+extern void mac_ax_selected_text_range P_ ((struct frame *, CFRange *));
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+extern unsigned int mac_ax_number_of_characters P_ ((struct frame *));
+#endif
+
+#if USE_MAC_TSM
+extern OSStatus mac_restore_keyboard_input_source P_ ((void));
+extern void mac_save_keyboard_input_source P_ ((void));
+
+static OSStatus
+mac_tsm_resume ()
+{
+ OSStatus err;
+
+ err = ActivateTSMDocument (tsm_document_id);
+ if (err == noErr)
+ err = mac_restore_keyboard_input_source ();
+
+ return err;
+}
+
+static OSStatus
+mac_tsm_suspend ()
+{
+ OSStatus err;
+
+ mac_save_keyboard_input_source ();
+ err = DeactivateTSMDocument (tsm_document_id);
+
+ return err;
+}
+
+static void
+init_tsm ()
+{
+#ifdef MAC_OSX
+ static InterfaceTypeList types = {kUnicodeDocument};
+#else
+ static InterfaceTypeList types = {kTextService};
+#endif
+
+ NewTSMDocument (sizeof (types) / sizeof (types[0]), types,
+ &tsm_document_id, 0);
+}
+#endif /* USE_MAC_TSM */
+
+static pascal OSStatus
+mac_handle_keyboard_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err, result = eventNotHandledErr;
+ UInt32 event_kind, key_code, modifiers;
+ unsigned char char_code;
+
+ event_kind = GetEventKind (event);
+ switch (event_kind)
+ {
+ case kEventRawKeyDown:
+ case kEventRawKeyRepeat:
+ case kEventRawKeyUp:
+ /* When using Carbon Events, we need to pass raw keyboard events
+ to the TSM ourselves. If TSM handles it, it will pass back
+ noErr, otherwise it will pass back "eventNotHandledErr" and
+ we can process it normally. */
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ break;
+
+ if (read_socket_inev == NULL)
+ break;
+
+#if USE_MAC_TSM
+ if (read_socket_inev->kind != NO_EVENT)
+ {
+ result = noErr;
+ break;
+ }
+#endif
+
+ if (event_kind == kEventRawKeyUp)
+ break;
+
+ err = GetEventParameter (event, kEventParamKeyMacCharCodes,
+ typeChar, NULL,
+ sizeof (char), NULL, &char_code);
+ if (err != noErr)
+ break;
+
+ err = GetEventParameter (event, kEventParamKeyCode,
+ typeUInt32, NULL,
+ sizeof (UInt32), NULL, &key_code);
+ if (err != noErr)
+ break;
+
+ err = GetEventParameter (event, kEventParamKeyModifiers,
+ typeUInt32, NULL,
+ sizeof (UInt32), NULL, &modifiers);
+ if (err != noErr)
+ break;
+
+ do_keystroke ((event_kind == kEventRawKeyDown ? keyDown : autoKey),
+ char_code, key_code, modifiers,
+ ((unsigned long)
+ (GetEventTime (event) / kEventDurationMillisecond)),
+ read_socket_inev);
+ result = noErr;
+ break;
+
+ default:
+ abort ();
+ }
+
+ return result;
+}
+
+static pascal OSStatus
+mac_handle_command_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err, result = eventNotHandledErr;
+ HICommand command;
+ static const EventParamName names[] =
+ {kEventParamDirectObject, kEventParamKeyModifiers};
+ static const EventParamType types[] =
+ {typeHICommand, typeUInt32};
+ int num_params = sizeof (names) / sizeof (names[0]);
+
+ err = GetEventParameter (event, kEventParamDirectObject, typeHICommand,
+ NULL, sizeof (HICommand), NULL, &command);
+ if (err != noErr)
+ return eventNotHandledErr;
+
+ switch (GetEventKind (event))
+ {
+ case kEventCommandProcess:
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ break;
+
+ err = GetEventParameter (event, kEventParamDirectObject,
+ typeHICommand, NULL,
+ sizeof (HICommand), NULL, &command);
+
+ if (err != noErr || command.commandID == 0)
+ break;
+
+ /* A HI command event is mapped to an Apple event whose event
+ class symbol is `hi-command' and event ID is its command
+ ID. */
+ err = mac_store_event_ref_as_apple_event (0, command.commandID,
+ Qhi_command, Qnil,
+ event, num_params,
+ names, types);
+ if (err == noErr)
+ result = noErr;
+ break;
+
+ default:
+ abort ();
+ }
+
+ return result;
+}
+
+static pascal OSStatus
+mac_handle_mouse_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err, result = eventNotHandledErr;
+
+ switch (GetEventKind (event))
+ {
+ case kEventMouseWheelMoved:
+ {
+ WindowRef wp;
+ struct frame *f;
+ EventMouseWheelAxis axis;
+ SInt32 delta;
+ Point point;
+
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr || read_socket_inev == NULL)
+ break;
+
+ f = mac_focus_frame (&one_mac_display_info);
+
+ err = GetEventParameter (event, kEventParamWindowRef, typeWindowRef,
+ NULL, sizeof (WindowRef), NULL, &wp);
+ if (err != noErr
+ || wp != FRAME_MAC_WINDOW (f))
+ break;
+
+ err = GetEventParameter (event, kEventParamMouseWheelAxis,
+ typeMouseWheelAxis, NULL,
+ sizeof (EventMouseWheelAxis), NULL, &axis);
+ if (err != noErr || axis != kEventMouseWheelAxisY)
+ break;
+
+ err = GetEventParameter (event, kEventParamMouseLocation,
+ typeQDPoint, NULL, sizeof (Point),
+ NULL, &point);
+ if (err != noErr)
+ break;
+
+ point.h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+ point.v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
+ if (point.h < 0 || point.v < 0
+ || EQ (window_from_coordinates (f, point.h, point.v, 0, 0, 0, 1),
+ f->tool_bar_window))
+ break;
+
+ err = GetEventParameter (event, kEventParamMouseWheelDelta,
+ typeSInt32, NULL, sizeof (SInt32),
+ NULL, &delta);
+ if (err != noErr)
+ break;
+
+ read_socket_inev->kind = WHEEL_EVENT;
+ read_socket_inev->code = 0;
+ read_socket_inev->modifiers =
+ (mac_event_to_emacs_modifiers (event)
+ | ((delta < 0) ? down_modifier : up_modifier));
+ XSETINT (read_socket_inev->x, point.h);
+ XSETINT (read_socket_inev->y, point.v);
+ XSETFRAME (read_socket_inev->frame_or_window, f);
+
+ result = noErr;
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ return result;
+}
+
+#if USE_MAC_TSM
+extern void mac_get_selected_range P_ ((struct window *, CFRange *));
+extern int mac_store_buffer_text_to_unicode_chars P_ ((struct buffer *,
+ int, int, UniChar *));
+
+static pascal OSStatus
+mac_handle_text_input_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err, result;
+ Lisp_Object id_key = Qnil;
+ int num_params;
+ const EventParamName *names;
+ const EventParamType *types;
+ static UInt32 seqno_uaia = 0;
+ static const EventParamName names_uaia[] =
+ {kEventParamTextInputSendComponentInstance,
+ kEventParamTextInputSendRefCon,
+ kEventParamTextInputSendSLRec,
+ kEventParamTextInputSendFixLen,
+ kEventParamTextInputSendText,
+ kEventParamTextInputSendUpdateRng,
+ kEventParamTextInputSendHiliteRng,
+ kEventParamTextInputSendClauseRng,
+ kEventParamTextInputSendPinRng,
+ kEventParamTextInputSendTextServiceEncoding,
+ kEventParamTextInputSendTextServiceMacEncoding,
+ EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER};
+ static const EventParamType types_uaia[] =
+ {typeComponentInstance,
+ typeLongInteger,
+ typeIntlWritingCode,
+ typeLongInteger,
+#ifdef MAC_OSX
+ typeUnicodeText,
+#else
+ typeChar,
+#endif
+ typeTextRangeArray,
+ typeTextRangeArray,
+ typeOffsetArray,
+ typeTextRange,
+ typeUInt32,
+ typeUInt32,
+ typeUInt32};
+ static const EventParamName names_ufke[] =
+ {kEventParamTextInputSendComponentInstance,
+ kEventParamTextInputSendRefCon,
+ kEventParamTextInputSendSLRec,
+ kEventParamTextInputSendText};
+ static const EventParamType types_ufke[] =
+ {typeComponentInstance,
+ typeLongInteger,
+ typeIntlWritingCode,
+ typeUnicodeText};
+
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ return result;
+
+ switch (GetEventKind (event))
+ {
+ case kEventTextInputUpdateActiveInputArea:
+ id_key = Qupdate_active_input_area;
+ num_params = sizeof (names_uaia) / sizeof (names_uaia[0]);
+ names = names_uaia;
+ types = types_uaia;
+ SetEventParameter (event, EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER,
+ typeUInt32, sizeof (UInt32), &seqno_uaia);
+ seqno_uaia++;
+ result = noErr;
+ break;
+
+ case kEventTextInputUnicodeForKeyEvent:
+ {
+ EventRef kbd_event;
+ UInt32 actual_size, modifiers, key_code;
+
+ err = GetEventParameter (event, kEventParamTextInputSendKeyboardEvent,
+ typeEventRef, NULL, sizeof (EventRef), NULL,
+ &kbd_event);
+ if (err == noErr)
+ err = GetEventParameter (kbd_event, kEventParamKeyModifiers,
+ typeUInt32, NULL,
+ sizeof (UInt32), NULL, &modifiers);
+ if (err == noErr)
+ err = GetEventParameter (kbd_event, kEventParamKeyCode,
+ typeUInt32, NULL, sizeof (UInt32),
+ NULL, &key_code);
+ if (err == noErr && mac_mapped_modifiers (modifiers, key_code))
+ /* There're mapped modifier keys. Process it in
+ do_keystroke. */
+ break;
+ if (err == noErr)
+ err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
+ typeUnicodeText, NULL, 0, &actual_size,
+ NULL);
+ if (err == noErr && actual_size == sizeof (UniChar))
+ {
+ UniChar code;
+
+ err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
+ typeUnicodeText, NULL,
+ sizeof (UniChar), NULL, &code);
+ if (err == noErr && code < 0x80)
+ {
+ /* ASCII character. Process it in do_keystroke. */
+ if (read_socket_inev && code >= 0x20 && code <= 0x7e
+ && !(key_code <= 0x7f
+ && keycode_to_xkeysym_table [key_code]))
+ {
+ struct frame *f = mac_focus_frame (&one_mac_display_info);
+
+ read_socket_inev->kind = ASCII_KEYSTROKE_EVENT;
+ read_socket_inev->code = code;
+ read_socket_inev->modifiers =
+ mac_to_emacs_modifiers (modifiers, 0);
+ read_socket_inev->modifiers |=
+ (extra_keyboard_modifiers
+ & (meta_modifier | alt_modifier
+ | hyper_modifier | super_modifier));
+ XSETFRAME (read_socket_inev->frame_or_window, f);
+ }
+ break;
+ }
+ }
+ if (err == noErr)
+ {
+ /* Non-ASCII keystrokes without mapped modifiers are
+ processed at the Lisp level. */
+ id_key = Qunicode_for_key_event;
+ num_params = sizeof (names_ufke) / sizeof (names_ufke[0]);
+ names = names_ufke;
+ types = types_ufke;
+ result = noErr;
+ }
+ }
+ break;
+
+ case kEventTextInputOffsetToPos:
+ {
+ long byte_offset;
+ struct frame *f;
+ struct window *w;
+ Point p;
+
+ err = GetEventParameter (event, kEventParamTextInputSendTextOffset,
+ typeLongInteger, NULL, sizeof (long), NULL,
+ &byte_offset);
+ if (err != noErr)
+ break;
+
+ if (STRINGP (Vmac_ts_active_input_buf)
+ && SBYTES (Vmac_ts_active_input_buf) != 0)
+ {
+ if (!OVERLAYP (Vmac_ts_active_input_overlay))
+ break;
+
+ /* Strictly speaking, this is not always correct because
+ previous events may change some states about display. */
+ if (!NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
+ {
+ /* Active input area is displayed around the current point. */
+ f = SELECTED_FRAME ();
+ w = XWINDOW (f->selected_window);
+ }
+ else if (WINDOWP (echo_area_window))
+ {
+ /* Active input area is displayed in the echo area. */
+ w = XWINDOW (echo_area_window);
+ f = WINDOW_XFRAME (w);
+ }
+ else
+ break;
+
+ p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
+ + WINDOW_LEFT_FRINGE_WIDTH (w)
+ + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
+ p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y)
+ + FONT_BASE (FRAME_FONT (f))
+ + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
+ }
+ else
+ {
+#ifndef MAC_OSX
+ break;
+#else /* MAC_OSX */
+ struct buffer *b;
+ CFRange sel_range;
+ int charpos;
+ int hpos, vpos, x, y;
+ struct glyph_row *row;
+ struct glyph *glyph;
+ struct face *face;
+
+ f = mac_focus_frame (&one_mac_display_info);
+ w = XWINDOW (f->selected_window);
+ b = XBUFFER (w->buffer);
+
+ /* Are we in a window whose display is up to date?
+ And verify the buffer's text has not changed. */
+ if (!(EQ (w->window_end_valid, w->buffer)
+ && XINT (w->last_modified) == BUF_MODIFF (b)
+ && XINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b)))
+ break;
+
+ mac_get_selected_range (w, &sel_range);
+ charpos = (BUF_BEGV (b) + sel_range.location
+ + byte_offset / (long) sizeof (UniChar));
+
+ if (!fast_find_position (w, charpos, &hpos, &vpos, &x, &y, Qnil))
+ {
+ result = errOffsetInvalid;
+ break;
+ }
+
+ row = MATRIX_ROW (w->current_matrix, vpos);
+ glyph = row->glyphs[TEXT_AREA] + hpos;
+ if (glyph->type != CHAR_GLYPH || glyph->glyph_not_available_p)
+ break;
+
+ p.h = (WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x)
+ + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
+ p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, y)
+ + row->visible_height
+ + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
+
+ face = FACE_FROM_ID (f, glyph->face_id);
+ if (face && face->font)
+ {
+ XFontStruct *font = face->font;
+ Fixed point_size = Long2Fix (font->mac_fontsize);
+ short height = row->visible_height;
+ short ascent = row->ascent;
+
+ SetEventParameter (event,
+ kEventParamTextInputReplyPointSize,
+ typeFixed, sizeof (Fixed), &point_size);
+ SetEventParameter (event,
+ kEventParamTextInputReplyLineHeight,
+ typeShortInteger, sizeof (short), &height);
+ SetEventParameter (event,
+ kEventParamTextInputReplyLineAscent,
+ typeShortInteger, sizeof (short), &ascent);
+ if (font->mac_fontnum != -1)
+ {
+ OSStatus err1;
+ FMFont fm_font;
+ FMFontStyle style;
+
+ err1 = FMGetFontFromFontFamilyInstance (font->mac_fontnum,
+ font->mac_fontface,
+ &fm_font, &style);
+ if (err1 == noErr)
+ SetEventParameter (event, kEventParamTextInputReplyFMFont,
+ typeUInt32, sizeof (UInt32), &fm_font);
+ else
+ {
+ long qd_font = font->mac_fontnum;
+
+ SetEventParameter (event, kEventParamTextInputReplyFont,
+ typeLongInteger, sizeof (long),
+ &qd_font);
+ }
+ }
+ else if (font->mac_style)
+ {
+ OSStatus err1;
+ ATSUFontID font_id;
+
+ err1 = ATSUGetAttribute (font->mac_style, kATSUFontTag,
+ sizeof (ATSUFontID), &font_id,
+ NULL);
+ if (err1 == noErr)
+ SetEventParameter (event, kEventParamTextInputReplyFMFont,
+ typeUInt32, sizeof (UInt32), &font_id);
+ }
+ else
+ abort ();
+ }
+#endif /* MAC_OSX */
+ }
+
+ err = SetEventParameter (event, kEventParamTextInputReplyPoint,
+ typeQDPoint, sizeof (Point), &p);
+ if (err == noErr)
+ result = noErr;
+ }
+ break;
+
+#ifdef MAC_OSX
+ case kEventTextInputPosToOffset:
+ {
+ Point point;
+ Boolean leading_edge_p = true;
+ struct frame *f;
+ int x, y;
+ Lisp_Object window;
+ enum window_part part;
+ long region_class = kTSMOutsideOfBody, byte_offset = 0;
+
+ err = GetEventParameter (event, kEventParamTextInputSendCurrentPoint,
+ typeQDPoint, NULL, sizeof (Point), NULL,
+ &point);
+ if (err != noErr)
+ break;
+
+ GetEventParameter (event, kEventParamTextInputReplyLeadingEdge,
+ typeBoolean, NULL, sizeof (Boolean), NULL,
+ &leading_edge_p);
+
+ f = mac_focus_frame (&one_mac_display_info);
+ x = point.h - (f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
+ y = point.v - (f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
+ window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
+ if (WINDOWP (window) && EQ (window, f->selected_window))
+ {
+ struct window *w;
+ struct buffer *b;
+
+ /* Convert to window-relative pixel coordinates. */
+ w = XWINDOW (window);
+ frame_to_window_pixel_xy (w, &x, &y);
+
+ /* Are we in a window whose display is up to date?
+ And verify the buffer's text has not changed. */
+ b = XBUFFER (w->buffer);
+ if (part == ON_TEXT
+ && EQ (w->window_end_valid, w->buffer)
+ && XINT (w->last_modified) == BUF_MODIFF (b)
+ && XINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
+ {
+ int hpos, vpos, area;
+ struct glyph *glyph;
+
+ /* Find the glyph under X/Y. */
+ glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, 0, 0, &area);
+
+ if (glyph != NULL && area == TEXT_AREA)
+ {
+ byte_offset = ((glyph->charpos - BUF_BEGV (b))
+ * sizeof (UniChar));
+ region_class = kTSMInsideOfBody;
+ }
+ }
+ }
+
+ err = SetEventParameter (event, kEventParamTextInputReplyRegionClass,
+ typeLongInteger, sizeof (long),
+ ®ion_class);
+ if (err == noErr)
+ err = SetEventParameter (event, kEventParamTextInputReplyTextOffset,
+ typeLongInteger, sizeof (long),
+ &byte_offset);
+ if (err == noErr)
+ result = noErr;
+ }
+ break;
+
+ case kEventTextInputGetSelectedText:
+ {
+ struct frame *f = mac_focus_frame (&one_mac_display_info);
+ struct window *w = XWINDOW (f->selected_window);
+ struct buffer *b = XBUFFER (w->buffer);
+ CFRange sel_range;
+ int start, end;
+ UniChar *characters, c;
+
+ if (poll_suppress_count == 0 && !NILP (Vinhibit_quit))
+ /* Don't try to get buffer contents as the gap might be
+ being altered. */
+ break;
+
+ mac_get_selected_range (w, &sel_range);
+ if (sel_range.length == 0)
+ {
+ Boolean leading_edge_p;
+
+ err = GetEventParameter (event,
+ kEventParamTextInputReplyLeadingEdge,
+ typeBoolean, NULL, sizeof (Boolean), NULL,
+ &leading_edge_p);
+ if (err != noErr)
+ break;
+
+ start = BUF_BEGV (b) + sel_range.location;
+ if (!leading_edge_p)
+ start--;
+ end = start + 1;
+ characters = &c;
+
+ if (start < BUF_BEGV (b) || end > BUF_ZV (b))
+ break;
+ }
+ else
+ {
+ start = BUF_BEGV (b) + sel_range.location;
+ end = start + sel_range.length;
+ characters = xmalloc (sel_range.length * sizeof (UniChar));
+ }
+
+ if (mac_store_buffer_text_to_unicode_chars (b, start, end, characters))
+ err = SetEventParameter (event, kEventParamTextInputReplyText,
+ typeUnicodeText,
+ sel_range.length * sizeof (UniChar),
+ characters);
+ if (characters != &c)
+ xfree (characters);
+
+ if (err == noErr)
+ result = noErr;
+ }
+ break;
+#endif /* MAC_OSX */
+
+ default:
+ abort ();
+ }
+
+ if (!NILP (id_key))
+ err = mac_store_event_ref_as_apple_event (0, 0, Qtext_input, id_key,
+ event, num_params,
+ names, types);
+ return result;
+}
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+static pascal OSStatus
+mac_handle_document_access_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err, result;
+ struct frame *f = mac_focus_frame (&one_mac_display_info);
+
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ return result;
+
+ switch (GetEventKind (event))
+ {
+ case kEventTSMDocumentAccessGetLength:
+ {
+ CFIndex count = mac_ax_number_of_characters (f);
+
+ err = SetEventParameter (event, kEventParamTSMDocAccessCharacterCount,
+ typeCFIndex, sizeof (CFIndex), &count);
+ if (err == noErr)
+ result = noErr;
+ }
+ break;
+
+ case kEventTSMDocumentAccessGetSelectedRange:
+ {
+ CFRange sel_range;
+
+ mac_ax_selected_text_range (f, &sel_range);
+ err = SetEventParameter (event,
+ kEventParamTSMDocAccessReplyCharacterRange,
+ typeCFRange, sizeof (CFRange), &sel_range);
+ if (err == noErr)
+ result = noErr;
+ }
+ break;
+
+ case kEventTSMDocumentAccessGetCharacters:
+ {
+ struct buffer *b = XBUFFER (XWINDOW (f->selected_window)->buffer);
+ CFRange range;
+ Ptr characters;
+ int start, end;
+
+ if (poll_suppress_count == 0 && !NILP (Vinhibit_quit))
+ /* Don't try to get buffer contents as the gap might be
+ being altered. */
+ break;
+
+ err = GetEventParameter (event,
+ kEventParamTSMDocAccessSendCharacterRange,
+ typeCFRange, NULL, sizeof (CFRange), NULL,
+ &range);
+ if (err == noErr)
+ err = GetEventParameter (event,
+ kEventParamTSMDocAccessSendCharactersPtr,
+ typePtr, NULL, sizeof (Ptr), NULL,
+ &characters);
+ if (err != noErr)
+ break;
+
+ start = BUF_BEGV (b) + range.location;
+ end = start + range.length;
+ if (mac_store_buffer_text_to_unicode_chars (b, start, end,
+ (UniChar *) characters))
+ result = noErr;
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ return result;
+}
+#endif
+#endif
+
+OSStatus
+install_application_handler ()
+{
+ OSStatus err = noErr;
+
+ if (err == noErr)
+ {
+ static const EventTypeSpec specs[] =
+ {{kEventClassKeyboard, kEventRawKeyDown},
+ {kEventClassKeyboard, kEventRawKeyRepeat},
+ {kEventClassKeyboard, kEventRawKeyUp}};
+
+ err = InstallApplicationEventHandler (NewEventHandlerUPP
+ (mac_handle_keyboard_event),
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+ }
+
+ if (err == noErr)
+ {
+ static const EventTypeSpec specs[] =
+ {{kEventClassCommand, kEventCommandProcess}};
+
+ err = InstallApplicationEventHandler (NewEventHandlerUPP
+ (mac_handle_command_event),
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+ }
+
+ if (err == noErr)
+ {
+ static const EventTypeSpec specs[] =
+ {{kEventClassMouse, kEventMouseWheelMoved}};
+
+ err = InstallApplicationEventHandler (NewEventHandlerUPP
+ (mac_handle_mouse_event),
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+ }
+
+#if USE_MAC_TSM
+ if (err == noErr)
+ {
+ static const EventTypeSpec specs[] =
+ {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
+ {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
+ {kEventClassTextInput, kEventTextInputOffsetToPos},
+#ifdef MAC_OSX
+ {kEventClassTextInput, kEventTextInputPosToOffset},
+ {kEventClassTextInput, kEventTextInputGetSelectedText}
+#endif
+ };
+
+ err = InstallApplicationEventHandler (NewEventHandlerUPP
+ (mac_handle_text_input_event),
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+ }
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ if (err == noErr)
+ {
+ static const EventTypeSpec specs[] =
+ {{kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength},
+ {kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange},
+ {kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters}};
+
+ err = InstallApplicationEventHandler (mac_handle_document_access_event,
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+ }
+#endif
+#endif
+
+ if (err == noErr)
+ err = install_menu_target_item_handler ();
+
+#ifdef MAC_OSX
+ if (err == noErr)
+ err = install_service_handler ();
+#endif
+
+ return err;
+}
+#endif /* TARGET_API_MAC_CARBON */
+
+\f
+/************************************************************************
+ Windows
+ ************************************************************************/
+
+#define DEFAULT_NUM_COLS 80
+
+#define MIN_DOC_SIZE 64
+#define MAX_DOC_SIZE 32767
+
+/* Drag and Drop */
+static OSErr install_drag_handler P_ ((WindowRef));
+static void remove_drag_handler P_ ((WindowRef));
+
+#if USE_CG_DRAWING
+static void mac_prepare_for_quickdraw P_ ((struct frame *));
+#endif
+
+extern void mac_handle_visibility_change P_ ((struct frame *));
+extern void mac_handle_origin_change P_ ((struct frame *));
+extern void mac_handle_size_change P_ ((struct frame *, int, int));
+
+#if TARGET_API_MAC_CARBON
+#ifdef MAC_OSX
+extern Lisp_Object Qwindow;
+extern Lisp_Object Qtoolbar_switch_mode;
+#endif
+#endif
+
+static void
+do_window_update (WindowRef win)
+{
+ struct frame *f = mac_window_to_frame (win);
+
+ BeginUpdate (win);
+
+ /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED
+ below. */
+ if (win != tip_window)
+ {
+ if (f->async_visible == 0)
+ {
+ /* Update events may occur when a frame gets iconified. */
+#if 0
+ f->async_visible = 1;
+ f->async_iconified = 0;
+ SET_FRAME_GARBAGED (f);
+#endif
+ }
+ else
+ {
+ Rect r;
+#if TARGET_API_MAC_CARBON
+ RgnHandle region = NewRgn ();
+
+ GetPortVisibleRegion (GetWindowPort (win), region);
+ GetRegionBounds (region, &r);
+ expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
+ UpdateControls (win, region);
+ DisposeRgn (region);
+#else
+ r = (*win->visRgn)->rgnBBox;
+ expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
+ UpdateControls (win, win->visRgn);
+#endif
+ }
+ }
+
+ EndUpdate (win);
+}
+
+static int
+is_emacs_window (WindowRef win)
+{
+ Lisp_Object tail, frame;
+
+ if (!win)
+ return 0;
+
+ FOR_EACH_FRAME (tail, frame)
+ if (FRAME_MAC_P (XFRAME (frame)))
+ if (FRAME_MAC_WINDOW (XFRAME (frame)) == win)
+ return 1;
+
+ return 0;
+}
+
+/* Handle drags in size box. Based on code contributed by Ben
+ Mesander and IM - Window Manager A. */
+
+static void
+do_grow_window (w, e)
+ WindowRef w;
+ const EventRecord *e;
+{
+ Rect limit_rect;
+ int rows, columns, width, height;
+ struct frame *f = mac_window_to_frame (w);
+ XSizeHints *size_hints = FRAME_SIZE_HINTS (f);
+ int min_width = MIN_DOC_SIZE, min_height = MIN_DOC_SIZE;
+#if TARGET_API_MAC_CARBON
+ Rect new_rect;
+#else
+ long grow_size;
+#endif
+
+ if (size_hints->flags & PMinSize)
+ {
+ min_width = size_hints->min_width;
+ min_height = size_hints->min_height;
+ }
+ SetRect (&limit_rect, min_width, min_height, MAX_DOC_SIZE, MAX_DOC_SIZE);
+
+#if TARGET_API_MAC_CARBON
+ if (!ResizeWindow (w, e->where, &limit_rect, &new_rect))
+ return;
+ height = new_rect.bottom - new_rect.top;
+ width = new_rect.right - new_rect.left;
+#else
+ grow_size = GrowWindow (w, e->where, &limit_rect);
+ /* see if it really changed size */
+ if (grow_size == 0)
+ return;
+ height = HiWord (grow_size);
+ width = LoWord (grow_size);
+#endif
+
+ if (width != FRAME_PIXEL_WIDTH (f)
+ || height != FRAME_PIXEL_HEIGHT (f))
+ {
+ rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
+ columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
+
+ x_set_window_size (f, 0, columns, rows);
+ }
+}
+
+#if TARGET_API_MAC_CARBON
+static Point
+mac_get_ideal_size (f)
+ struct frame *f;
+{
+ struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+ WindowRef w = FRAME_MAC_WINDOW (f);
+ Point ideal_size;
+ Rect standard_rect;
+ int height, width, columns, rows;
+
+ ideal_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
+ ideal_size.v = dpyinfo->height;
+ IsWindowInStandardState (w, &ideal_size, &standard_rect);
+ /* Adjust the standard size according to character boundaries. */
+ width = standard_rect.right - standard_rect.left;
+ height = standard_rect.bottom - standard_rect.top;
+ columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
+ rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
+ ideal_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, columns);
+ ideal_size.v = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+
+ return ideal_size;
+}
+
+static pascal OSStatus
+mac_handle_window_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ WindowRef wp;
+ OSStatus err, result = eventNotHandledErr;
+ struct frame *f;
+ UInt32 attributes;
+ XSizeHints *size_hints;
+
+ err = GetEventParameter (event, kEventParamDirectObject, typeWindowRef,
+ NULL, sizeof (WindowRef), NULL, &wp);
+ if (err != noErr)
+ return eventNotHandledErr;
+
+ f = mac_window_to_frame (wp);
+ switch (GetEventKind (event))
+ {
+ /* -- window refresh events -- */
+
+ case kEventWindowUpdate:
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ break;
+
+ do_window_update (wp);
+ result = noErr;
+ break;
+
+ /* -- window state change events -- */
+
+ case kEventWindowShowing:
+ size_hints = FRAME_SIZE_HINTS (f);
+ if (!(size_hints->flags & (USPosition | PPosition)))
+ {
+ struct frame *sf = SELECTED_FRAME ();
+
+ if (!(FRAME_MAC_P (sf) && sf->async_visible))
+ RepositionWindow (wp, NULL, kWindowCenterOnMainScreen);
+ else
+ {
+ RepositionWindow (wp, FRAME_MAC_WINDOW (sf),
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ kWindowCascadeStartAtParentWindowScreen
+#else
+ kWindowCascadeOnParentWindowScreen
+#endif
+ );
+#if USE_MAC_TOOLBAR
+ /* This is a workaround. RepositionWindow fails to put
+ a window at the cascading position when its parent
+ window has a Carbon HIToolbar. */
+ if ((f->left_pos == sf->left_pos
+ && f->top_pos == sf->top_pos)
+ || (f->left_pos == sf->left_pos + 10 * 2
+ && f->top_pos == sf->top_pos + 32 * 2))
+ MoveWindowStructure (wp, sf->left_pos + 10, sf->top_pos + 32);
+#endif
+ }
+ result = noErr;
+ }
+ break;
+
+ case kEventWindowHiding:
+ /* Before unmapping the window, update the WM_SIZE_HINTS
+ property to claim that the current position of the window is
+ user-specified, rather than program-specified, so that when
+ the window is mapped again, it will be placed at the same
+ location, without forcing the user to position it by hand
+ again (they have already done that once for this window.) */
+ x_wm_set_size_hint (f, (long) 0, 1);
+ result = noErr;
+ break;
+
+ case kEventWindowShown:
+ case kEventWindowHidden:
+ case kEventWindowCollapsed:
+ case kEventWindowExpanded:
+ mac_handle_visibility_change (f);
+ result = noErr;
+ break;
+
+ case kEventWindowBoundsChanging:
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ break;
+
+ err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
+ NULL, sizeof (UInt32), NULL, &attributes);
+ if (err != noErr)
+ break;
+
+ size_hints = FRAME_SIZE_HINTS (f);
+ if ((attributes & kWindowBoundsChangeUserResize)
+ && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize))
+ == (PResizeInc | PBaseSize | PMinSize)))
+ {
+ Rect bounds;
+ int width, height;
+
+ err = GetEventParameter (event, kEventParamCurrentBounds,
+ typeQDRectangle, NULL, sizeof (Rect),
+ NULL, &bounds);
+ if (err != noErr)
+ break;
+
+ width = bounds.right - bounds.left;
+ height = bounds.bottom - bounds.top;
+
+ if (width < size_hints->min_width)
+ width = size_hints->min_width;
+ else
+ width = size_hints->base_width
+ + (int) ((width - size_hints->base_width)
+ / (float) size_hints->width_inc + .5)
+ * size_hints->width_inc;
+
+ if (height < size_hints->min_height)
+ height = size_hints->min_height;
+ else
+ height = size_hints->base_height
+ + (int) ((height - size_hints->base_height)
+ / (float) size_hints->height_inc + .5)
+ * size_hints->height_inc;
+
+ bounds.right = bounds.left + width;
+ bounds.bottom = bounds.top + height;
+ SetEventParameter (event, kEventParamCurrentBounds,
+ typeQDRectangle, sizeof (Rect), &bounds);
+ result = noErr;
+ }
+ break;
+
+ case kEventWindowBoundsChanged:
+ err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
+ NULL, sizeof (UInt32), NULL, &attributes);
+ if (err != noErr)
+ break;
+
+ if (attributes & kWindowBoundsChangeSizeChanged)
+ {
+ Rect bounds;
+
+ err = GetEventParameter (event, kEventParamCurrentBounds,
+ typeQDRectangle, NULL, sizeof (Rect),
+ NULL, &bounds);
+ if (err == noErr)
+ {
+ int width, height;
+
+ width = bounds.right - bounds.left;
+ height = bounds.bottom - bounds.top;
+ mac_handle_size_change (f, width, height);
+ mac_wakeup_from_rne ();
+ }
+ }
+
+ if (attributes & kWindowBoundsChangeOriginChanged)
+ mac_handle_origin_change (f);
+
+ result = noErr;
+ break;
+
+ /* -- window action events -- */
+
+ case kEventWindowClose:
+ {
+ struct input_event buf;
+
+ EVENT_INIT (buf);
+ buf.kind = DELETE_WINDOW_EVENT;
+ XSETFRAME (buf.frame_or_window, f);
+ buf.arg = Qnil;
+ kbd_buffer_store_event (&buf);
+ }
+ result = noErr;
+ break;
+
+ case kEventWindowGetIdealSize:
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ break;
+
+ {
+ Point ideal_size = mac_get_ideal_size (f);
+
+ err = SetEventParameter (event, kEventParamDimensions,
+ typeQDPoint, sizeof (Point), &ideal_size);
+ if (err == noErr)
+ result = noErr;
+ }
+ break;
+
+#ifdef MAC_OSX
+ case kEventWindowToolbarSwitchMode:
+ {
+ static const EventParamName names[] = {kEventParamDirectObject,
+ kEventParamWindowMouseLocation,
+ kEventParamKeyModifiers,
+ kEventParamMouseButton,
+ kEventParamClickCount,
+ kEventParamMouseChord};
+ static const EventParamType types[] = {typeWindowRef,
+ typeQDPoint,
+ typeUInt32,
+ typeMouseButton,
+ typeUInt32,
+ typeUInt32};
+ int num_params = sizeof (names) / sizeof (names[0]);
+
+ err = mac_store_event_ref_as_apple_event (0, 0,
+ Qwindow,
+ Qtoolbar_switch_mode,
+ event, num_params,
+ names, types);
+ }
+ if (err == noErr)
+ result = noErr;
+ break;
+#endif
+
+#if USE_MAC_TSM
+ /* -- window focus events -- */
+
+ case kEventWindowFocusAcquired:
+ err = mac_tsm_resume ();
+ if (err == noErr)
+ result = noErr;
+ break;
+
+ case kEventWindowFocusRelinquish:
+ err = mac_tsm_suspend ();
+ if (err == noErr)
+ result = noErr;
+ break;
+#endif
+
+ default:
+ abort ();
+ }
+
+ return result;
+}
+#endif
+
+/* Handle clicks in zoom box. Calculation of "standard state" based
+ on code in IM - Window Manager A and code contributed by Ben
+ Mesander. The standard state of an Emacs window is 80-characters
+ wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
+
+static void
+do_zoom_window (WindowRef w, int zoom_in_or_out)
+{
+ Rect zoom_rect, port_rect;
+ int width, height;
+ struct frame *f = mac_window_to_frame (w);
+#if TARGET_API_MAC_CARBON
+ Point ideal_size = mac_get_ideal_size (f);
+
+ GetWindowBounds (w, kWindowContentRgn, &port_rect);
+ if (IsWindowInStandardState (w, &ideal_size, &zoom_rect)
+ && port_rect.left == zoom_rect.left
+ && port_rect.top == zoom_rect.top)
+ zoom_in_or_out = inZoomIn;
+ else
+ zoom_in_or_out = inZoomOut;
+
+#ifdef MAC_OS8
+ mac_clear_area (f, 0, 0, port_rect.right - port_rect.left,
+ port_rect.bottom - port_rect.top);
+#endif
+ ZoomWindowIdeal (w, zoom_in_or_out, &ideal_size);
+#else /* not TARGET_API_MAC_CARBON */
+ GrafPtr save_port;
+ Point top_left;
+ int w_title_height, rows;
+ struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+
+ GetPort (&save_port);
+
+ SetPortWindowPort (w);
+
+ /* Clear window to avoid flicker. */
+ EraseRect (&(w->portRect));
+ if (zoom_in_or_out == inZoomOut)
+ {
+ SetPt (&top_left, w->portRect.left, w->portRect.top);
+ LocalToGlobal (&top_left);
+
+ /* calculate height of window's title bar */
+ w_title_height = top_left.v - 1
+ - (**((WindowPeek) w)->strucRgn).rgnBBox.top + GetMBarHeight ();
+
+ /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
+ zoom_rect = qd.screenBits.bounds;
+ zoom_rect.top += w_title_height;
+ InsetRect (&zoom_rect, 8, 4); /* not too tight */
+
+ zoom_rect.right = zoom_rect.left
+ + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
+
+ /* Adjust the standard size according to character boundaries. */
+ rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, zoom_rect.bottom - zoom_rect.top);
+ zoom_rect.bottom =
+ zoom_rect.top + FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+
+ (**((WStateDataHandle) ((WindowPeek) w)->dataHandle)).stdState
+ = zoom_rect;
+ }
+
+ ZoomWindow (w, zoom_in_or_out, f == mac_focus_frame (dpyinfo));
+
+ SetPort (save_port);
+#endif /* not TARGET_API_MAC_CARBON */
+
+#if !TARGET_API_MAC_CARBON
+ /* retrieve window size and update application values */
+ port_rect = w->portRect;
+ height = port_rect.bottom - port_rect.top;
+ width = port_rect.right - port_rect.left;
+
+ mac_handle_size_change (f, width, height);
+ mac_handle_origin_change (f);
+#endif
+}
+
+static OSStatus
+install_window_handler (window)
+ WindowRef window;
+{
+ OSStatus err = noErr;
+
+#if TARGET_API_MAC_CARBON
+ if (err == noErr)
+ {
+ static const EventTypeSpec specs[] =
+ {
+ /* -- window refresh events -- */
+ {kEventClassWindow, kEventWindowUpdate},
+ /* -- window state change events -- */
+ {kEventClassWindow, kEventWindowShowing},
+ {kEventClassWindow, kEventWindowHiding},
+ {kEventClassWindow, kEventWindowShown},
+ {kEventClassWindow, kEventWindowHidden},
+ {kEventClassWindow, kEventWindowCollapsed},
+ {kEventClassWindow, kEventWindowExpanded},
+ {kEventClassWindow, kEventWindowBoundsChanging},
+ {kEventClassWindow, kEventWindowBoundsChanged},
+ /* -- window action events -- */
+ {kEventClassWindow, kEventWindowClose},
+ {kEventClassWindow, kEventWindowGetIdealSize},
+#ifdef MAC_OSX
+ {kEventClassWindow, kEventWindowToolbarSwitchMode},
+#endif
+#if USE_MAC_TSM
+ /* -- window focus events -- */
+ {kEventClassWindow, kEventWindowFocusAcquired},
+ {kEventClassWindow, kEventWindowFocusRelinquish},
+#endif
+ };
+ static EventHandlerUPP handle_window_eventUPP = NULL;
+
+ if (handle_window_eventUPP == NULL)
+ handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event);
+
+ err = InstallWindowEventHandler (window, handle_window_eventUPP,
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+ }
+#endif
+
+ if (err == noErr)
+ err = install_drag_handler (window);
+
+ return err;
+}
+
+static void
+remove_window_handler (window)
+ WindowRef window;
+{
+ remove_drag_handler (window);
+}
+
+void
+mac_get_window_bounds (f, inner, outer)
+ struct frame *f;
+ Rect *inner, *outer;
+{
+#if TARGET_API_MAC_CARBON
+ GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowContentRgn, inner);
+ GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowStructureRgn, outer);
+#else /* not TARGET_API_MAC_CARBON */
+ RgnHandle region = NewRgn ();
+
+ GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowContentRgn, region);
+ *inner = (*region)->rgnBBox;
+ GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowStructureRgn, region);
+ *outer = (*region)->rgnBBox;
+ DisposeRgn (region);
+#endif /* not TARGET_API_MAC_CARBON */
+}
+
+Rect *
+mac_get_frame_bounds (f, r)
+ struct frame *f;
+ Rect *r;
+{
+#if TARGET_API_MAC_CARBON
+ return GetWindowPortBounds (FRAME_MAC_WINDOW (f), r);
+#else
+ *r = FRAME_MAC_WINDOW (f)->portRect;
+
+ return r;
+#endif
+}
+
+void
+mac_get_frame_mouse (f, point)
+ struct frame *f;
+ Point *point;
+{
+#if TARGET_API_MAC_CARBON
+ GetGlobalMouse (point);
+ point->h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+ point->v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
+#else
+ SetPortWindowPort (FRAME_MAC_WINDOW (f));
+ GetMouse (point);
+#endif
+}
+
+void
+mac_convert_frame_point_to_global (f, x, y)
+ struct frame *f;
+ int *x, *y;
+{
+ *x += f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+ *y += f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
+}
+
+#if TARGET_API_MAC_CARBON
+void
+mac_update_proxy_icon (f)
+ struct frame *f;
+{
+ OSStatus err;
+ Lisp_Object file_name =
+ XBUFFER (XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer)->filename;
+ Window w = FRAME_MAC_WINDOW (f);
+ AliasHandle alias = NULL;
+
+ err = GetWindowProxyAlias (w, &alias);
+ if (err == errWindowDoesNotHaveProxy && !STRINGP (file_name))
+ return;
+
+ if (STRINGP (file_name))
+ {
+ AEDesc desc;
+#ifdef MAC_OSX
+ FSRef fref, fref_proxy;
+#else
+ FSSpec fss, fss_proxy;
+#endif
+ Boolean changed;
+ Lisp_Object encoded_file_name = ENCODE_FILE (file_name);
+
+#ifdef MAC_OSX
+ err = AECoercePtr (TYPE_FILE_NAME, SDATA (encoded_file_name),
+ SBYTES (encoded_file_name), typeFSRef, &desc);
+#else
+ SetPortWindowPort (w);
+ err = AECoercePtr (TYPE_FILE_NAME, SDATA (encoded_file_name),
+ SBYTES (encoded_file_name), typeFSS, &desc);
+#endif
+ if (err == noErr)
+ {
+#ifdef MAC_OSX
+ err = AEGetDescData (&desc, &fref, sizeof (FSRef));
+#else
+ err = AEGetDescData (&desc, &fss, sizeof (FSSpec));
+#endif
+ AEDisposeDesc (&desc);
+ }
+ if (err == noErr)
+ {
+ if (alias)
+ {
+ /* (FS)ResolveAlias never sets `changed' to true if
+ `alias' is minimal. */
+#ifdef MAC_OSX
+ err = FSResolveAlias (NULL, alias, &fref_proxy, &changed);
+ if (err == noErr)
+ err = FSCompareFSRefs (&fref, &fref_proxy);
+#else
+ err = ResolveAlias (NULL, alias, &fss_proxy, &changed);
+ if (err == noErr)
+ err = !(fss.vRefNum == fss_proxy.vRefNum
+ && fss.parID == fss_proxy.parID
+ && EqualString (fss.name, fss_proxy.name,
+ false, true));
+#endif
+ }
+ if (err != noErr || alias == NULL)
+ {
+ if (alias)
+ DisposeHandle ((Handle) alias);
+#ifdef MAC_OSX
+ err = FSNewAliasMinimal (&fref, &alias);
+#else
+ err = NewAliasMinimal (&fss, &alias);
+#endif
+ changed = true;
+ }
+ }
+ if (err == noErr)
+ if (changed)
+ err = SetWindowProxyAlias (w, alias);
+ }
+
+ if (alias)
+ DisposeHandle ((Handle) alias);
+
+ if (err != noErr || !STRINGP (file_name))
+ RemoveWindowProxy (w);
+}
+#endif
+
+/* Mac replacement for XSetWindowBackground. */
+
+void
+mac_set_frame_window_background (f, color)
+ struct frame *f;
+ unsigned long color;
+{
+ WindowRef w = FRAME_MAC_WINDOW (f);
+#if !TARGET_API_MAC_CARBON
+ AuxWinHandle aw_handle;
+ CTabHandle ctab_handle;
+ ColorSpecPtr ct_table;
+ short ct_size;
+#endif
+ RGBColor bg_color;
+
+ bg_color.red = RED16_FROM_ULONG (color);
+ bg_color.green = GREEN16_FROM_ULONG (color);
+ bg_color.blue = BLUE16_FROM_ULONG (color);
+
+#if TARGET_API_MAC_CARBON
+ SetWindowContentColor (w, &bg_color);
+#else
+ if (GetAuxWin (w, &aw_handle))
+ {
+ ctab_handle = (*aw_handle)->awCTable;
+ HandToHand ((Handle *) &ctab_handle);
+ ct_table = (*ctab_handle)->ctTable;
+ ct_size = (*ctab_handle)->ctSize;
+ while (ct_size > -1)
+ {
+ if (ct_table->value == 0)
+ {
+ ct_table->rgb = bg_color;
+ CTabChanged (ctab_handle);
+ SetWinColor (w, (WCTabHandle) ctab_handle);
+ }
+ ct_size--;
+ }
+ }
+#endif
+}
+
+/* Flush display of frame F, or of all frames if F is null. */
+
+void
+x_flush (f)
+ struct frame *f;
+{
+#if TARGET_API_MAC_CARBON
+ BLOCK_INPUT;
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
+ if (f)
+ QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f)), NULL);
+ else
+ QDFlushPortBuffer (GetQDGlobalsThePort (), NULL);
+ UNBLOCK_INPUT;
+#endif
+}
+
+#if USE_CG_DRAWING
+void
+mac_flush_display_optional (f)
+ struct frame *f;
+{
+ BLOCK_INPUT;
+ mac_prepare_for_quickdraw (f);
+ UNBLOCK_INPUT;
+}
+#endif
+
+void
+mac_update_begin (f)
+ struct frame *f;
+{
+#if TARGET_API_MAC_CARBON
+ /* During update of a frame, availability of input events is
+ periodically checked with ReceiveNextEvent if
+ redisplay-dont-pause is nil. That normally flushes window buffer
+ changes for every check, and thus screen update looks waving even
+ if no input is available. So we disable screen updates during
+ update of a frame. */
+ DisableScreenUpdates ();
+#endif
+}
+
+void
+mac_update_end (f)
+ struct frame *f;
+{
+#if TARGET_API_MAC_CARBON
+ EnableScreenUpdates ();
+#endif
+}
+
+void
+mac_frame_up_to_date (f)
+ struct frame *f;
+{
+ /* Nothing to do. */
+}
+
+void
+mac_create_frame_window (f, tooltip_p)
+ struct frame *f;
+ int tooltip_p;
+{
+ Rect r;
+#if TARGET_API_MAC_CARBON
+ WindowClass window_class;
+ WindowAttributes attributes;
+#else
+ short proc_id;
+ WindowRef behind;
+ Boolean go_away_flag;
+#endif
+
+ if (!tooltip_p)
+ {
+ SetRect (&r, f->left_pos, f->top_pos,
+ f->left_pos + FRAME_PIXEL_WIDTH (f),
+ f->top_pos + FRAME_PIXEL_HEIGHT (f));
+#if TARGET_API_MAC_CARBON
+ window_class = kDocumentWindowClass;
+ attributes = (kWindowStandardDocumentAttributes
+#ifdef MAC_OSX
+ | kWindowToolbarButtonAttribute
+#endif
+ );
+#else
+ proc_id = zoomDocProc;
+ behind = (WindowRef) -1;
+ go_away_flag = true;
+#endif
+ }
+ else
+ {
+ SetRect (&r, 0, 0, 1, 1);
+#if TARGET_API_MAC_CARBON
+ window_class = kHelpWindowClass;
+ attributes = (kWindowNoUpdatesAttribute
+ | kWindowNoActivatesAttribute
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ | kWindowIgnoreClicksAttribute
+#endif
+ );
+#else
+ proc_id = plainDBox;
+ behind = NULL;
+ go_away_flag = false;
+#endif
+ }
+
+#if TARGET_API_MAC_CARBON
+ CreateNewWindow (window_class, attributes, &r, &FRAME_MAC_WINDOW (f));
+ if (FRAME_MAC_WINDOW (f))
+ {
+ SetWRefCon (FRAME_MAC_WINDOW (f), (long) f->output_data.mac);
+ if (!tooltip_p)
+ if (install_window_handler (FRAME_MAC_WINDOW (f)) != noErr)
+ {
+ DisposeWindow (FRAME_MAC_WINDOW (f));
+ FRAME_MAC_WINDOW (f) = NULL;
+ }
+ }
+#else /* !TARGET_API_MAC_CARBON */
+ FRAME_MAC_WINDOW (f)
+ = NewCWindow (NULL, &r, "\p", false, proc_id, behind, go_away_flag,
+ (long) f->output_data.mac);
+#endif /* !TARGET_API_MAC_CARBON */
+ /* so that update events can find this mac_output struct */
+ f->output_data.mac->mFP = f; /* point back to emacs frame */
+
+#ifndef MAC_OSX
+ if (!tooltip_p)
+ if (FRAME_MAC_WINDOW (f))
+ {
+ ControlRef root_control;
+
+ if (CreateRootControl (FRAME_MAC_WINDOW (f), &root_control) != noErr)
+ {
+ DisposeWindow (FRAME_MAC_WINDOW (f));
+ FRAME_MAC_WINDOW (f) = NULL;
+ }
+ }
+#endif
+}
+
+/* Dispose of the Mac window of the frame F. */
+
+void
+mac_dispose_frame_window (f)
+ struct frame *f;
+{
+ WindowRef window = FRAME_MAC_WINDOW (f);
+
+ if (window != tip_window)
+ remove_window_handler (window);
+
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
+ DisposeWindow (window);
+}
+
+\f
+/************************************************************************
+ View and Drawing
+ ************************************************************************/
+
+#if USE_CG_DRAWING
+#define FRAME_CG_CONTEXT(f) ((f)->output_data.mac->cg_context)
+
+CGContextRef
+mac_begin_cg_clip (f, gc)
+ struct frame *f;
+ GC gc;
+{
+ CGContextRef context = FRAME_CG_CONTEXT (f);
+
+ if (!context)
+ {
+ QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
+ FRAME_CG_CONTEXT (f) = context;
+ }
+
+ CGContextSaveGState (context);
+ CGContextTranslateCTM (context, 0, FRAME_PIXEL_HEIGHT (f));
+ CGContextScaleCTM (context, 1, -1);
+ if (gc && gc->n_clip_rects)
+ CGContextClipToRects (context, gc->clip_rects, gc->n_clip_rects);
+
+ return context;
+}
+
+void
+mac_end_cg_clip (f)
+ struct frame *f;
+{
+ CGContextRestoreGState (FRAME_CG_CONTEXT (f));
+}
+
+static void
+mac_prepare_for_quickdraw (f)
+ struct frame *f;
+{
+ if (f == NULL)
+ {
+ Lisp_Object rest, frame;
+ FOR_EACH_FRAME (rest, frame)
+ if (FRAME_MAC_P (XFRAME (frame)))
+ mac_prepare_for_quickdraw (XFRAME (frame));
+ }
+ else
+ {
+ CGContextRef context = FRAME_CG_CONTEXT (f);
+
+ if (context)
+ {
+ CGContextSynchronize (context);
+ QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)),
+ &FRAME_CG_CONTEXT (f));
+ }
+ }
+}
+#endif
+
+static RgnHandle saved_port_clip_region = NULL;
+
+void
+mac_begin_clip (f, gc)
+ struct frame *f;
+ GC gc;
+{
+ static RgnHandle new_region = NULL;
+
+ if (saved_port_clip_region == NULL)
+ saved_port_clip_region = NewRgn ();
+ if (new_region == NULL)
+ new_region = NewRgn ();
+
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
+ SetPortWindowPort (FRAME_MAC_WINDOW (f));
+
+ if (gc && gc->n_clip_rects)
+ {
+ GetClip (saved_port_clip_region);
+ SectRgn (saved_port_clip_region, gc->clip_region, new_region);
+ SetClip (new_region);
+ }
+}
+
+void
+mac_end_clip (f, gc)
+ struct frame *f;
+ GC gc;
+{
+ if (gc && gc->n_clip_rects)
+ SetClip (saved_port_clip_region);
+}
+
+#if TARGET_API_MAC_CARBON
+/* Mac replacement for XCopyArea: used only for scrolling. */
+
+void
+mac_scroll_area (f, gc, src_x, src_y, width, height, dest_x, dest_y)
+ struct frame *f;
+ GC gc;
+ int src_x, src_y;
+ unsigned int width, height;
+ int dest_x, dest_y;
+{
+ Rect src_r;
+ RgnHandle dummy = NewRgn (); /* For avoiding update events. */
+
+ SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
+ ScrollWindowRect (FRAME_MAC_WINDOW (f),
+ &src_r, dest_x - src_x, dest_y - src_y,
+ kScrollWindowNoOptions, dummy);
+ DisposeRgn (dummy);
+}
+#endif
+
+\f
+/************************************************************************
+ Scroll bars
+ ************************************************************************/
+
+extern struct scroll_bar *tracked_scroll_bar;
+extern Lisp_Object last_mouse_scroll_bar;
+extern Time last_mouse_movement_time;
+
+static void x_scroll_bar_handle_click P_ ((struct scroll_bar *,
+ ControlPartCode,
+ const EventRecord *,
+ struct input_event *));
+#ifndef USE_TOOLKIT_SCROLL_BARS
+static void x_scroll_bar_note_movement P_ ((struct scroll_bar *, int, Time));
+#else /* USE_TOOLKIT_SCROLL_BARS */
+static void x_scroll_bar_handle_press P_ ((struct scroll_bar *,
+ ControlPartCode, Point,
+ struct input_event *));
+static void x_scroll_bar_handle_release P_ ((struct scroll_bar *,
+ struct input_event *));
+static void x_scroll_bar_handle_drag P_ ((WindowRef, struct scroll_bar *,
+ Point, struct input_event *));
+static pascal void scroll_bar_timer_callback P_ ((EventLoopTimerRef, void *));
+static OSStatus install_scroll_bar_timer P_ ((void));
+static OSStatus set_scroll_bar_timer P_ ((EventTimerInterval));
+static int control_part_code_to_scroll_bar_part P_ ((ControlPartCode));
+static void construct_scroll_bar_click P_ ((struct scroll_bar *, int,
+ struct input_event *));
+static OSStatus get_control_part_bounds P_ ((ControlRef, ControlPartCode,
+ Rect *));
+static void update_scroll_bar_track_info P_ ((struct scroll_bar *));
+
+/* Last scroll bar part sent in x_scroll_bar_handle_*. */
+
+static int last_scroll_bar_part;
+
+static EventLoopTimerRef scroll_bar_timer;
+
+static int scroll_bar_timer_event_posted_p;
+
+#define SCROLL_BAR_FIRST_DELAY 0.5
+#define SCROLL_BAR_CONTINUOUS_DELAY (1.0 / 15)
+
+static pascal void
+scroll_bar_timer_callback (timer, data)
+ EventLoopTimerRef timer;
+ void *data;
+{
+ OSStatus err;
+
+ err = mac_post_mouse_moved_event ();
+ if (err == noErr)
+ scroll_bar_timer_event_posted_p = 1;
+}
+
+static OSStatus
+install_scroll_bar_timer ()
+{
+ static EventLoopTimerUPP scroll_bar_timer_callbackUPP = NULL;
+
+ if (scroll_bar_timer_callbackUPP == NULL)
+ scroll_bar_timer_callbackUPP =
+ NewEventLoopTimerUPP (scroll_bar_timer_callback);
+
+ if (scroll_bar_timer == NULL)
+ /* Mac OS X and CarbonLib 1.5 and later allow us to specify
+ kEventDurationForever as delays. */
+ return
+ InstallEventLoopTimer (GetCurrentEventLoop (),
+ kEventDurationForever, kEventDurationForever,
+ scroll_bar_timer_callbackUPP, NULL,
+ &scroll_bar_timer);
+}
+
+static OSStatus
+set_scroll_bar_timer (delay)
+ EventTimerInterval delay;
+{
+ if (scroll_bar_timer == NULL)
+ install_scroll_bar_timer ();
+
+ scroll_bar_timer_event_posted_p = 0;
+
+ return SetEventLoopTimerNextFireTime (scroll_bar_timer, delay);
+}
+
+static int
+control_part_code_to_scroll_bar_part (part_code)
+ ControlPartCode part_code;
+{
+ switch (part_code)
+ {
+ case kControlUpButtonPart: return scroll_bar_up_arrow;
+ case kControlDownButtonPart: return scroll_bar_down_arrow;
+ case kControlPageUpPart: return scroll_bar_above_handle;
+ case kControlPageDownPart: return scroll_bar_below_handle;
+ case kControlIndicatorPart: return scroll_bar_handle;
+ }
+
+ return -1;
+}
+
+static void
+construct_scroll_bar_click (bar, part, bufp)
+ struct scroll_bar *bar;
+ int part;
+ struct input_event *bufp;
+{
+ bufp->kind = SCROLL_BAR_CLICK_EVENT;
+ bufp->frame_or_window = bar->window;
+ bufp->arg = Qnil;
+ bufp->part = part;
+ bufp->code = 0;
+ XSETINT (bufp->x, 0);
+ XSETINT (bufp->y, 0);
+ bufp->modifiers = 0;
+}
+
+static OSStatus
+get_control_part_bounds (ch, part_code, rect)
+ ControlRef ch;
+ ControlPartCode part_code;
+ Rect *rect;
+{
+ RgnHandle region = NewRgn ();
+ OSStatus err;
+
+ err = GetControlRegion (ch, part_code, region);
+ if (err == noErr)
+ GetRegionBounds (region, rect);
+ DisposeRgn (region);
+
+ return err;
+}
+
+static void
+x_scroll_bar_handle_press (bar, part_code, mouse_pos, bufp)
+ struct scroll_bar *bar;
+ ControlPartCode part_code;
+ Point mouse_pos;
+ struct input_event *bufp;
+{
+ int part = control_part_code_to_scroll_bar_part (part_code);
+
+ if (part < 0)
+ return;
+
+ if (part != scroll_bar_handle)
+ {
+ construct_scroll_bar_click (bar, part, bufp);
+ HiliteControl (SCROLL_BAR_CONTROL_REF (bar), part_code);
+ set_scroll_bar_timer (SCROLL_BAR_FIRST_DELAY);
+ bar->dragging = Qnil;
+ }
+ else
+ {
+ Rect r;
+
+ get_control_part_bounds (SCROLL_BAR_CONTROL_REF (bar),
+ kControlIndicatorPart, &r);
+ XSETINT (bar->dragging, - (mouse_pos.v - r.top) - 1);
+ }
+
+ last_scroll_bar_part = part;
+ tracked_scroll_bar = bar;
+}
+
+static void
+x_scroll_bar_handle_release (bar, bufp)
+ struct scroll_bar *bar;
+ struct input_event *bufp;
+{
+ if (last_scroll_bar_part != scroll_bar_handle
+ || (INTEGERP (bar->dragging) && XINT (bar->dragging) >= 0))
+ construct_scroll_bar_click (bar, scroll_bar_end_scroll, bufp);
+
+ HiliteControl (SCROLL_BAR_CONTROL_REF (bar), 0);
+ set_scroll_bar_timer (kEventDurationForever);
+
+ last_scroll_bar_part = -1;
+ bar->dragging = Qnil;
+ tracked_scroll_bar = NULL;
+}
+
+static void
+x_scroll_bar_handle_drag (win, bar, mouse_pos, bufp)
+ WindowRef win;
+ struct scroll_bar *bar;
+ Point mouse_pos;
+ struct input_event *bufp;
+{
+ ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
+
+ if (last_scroll_bar_part == scroll_bar_handle)
+ {
+ int top, top_range;
+ Rect r;
+
+ get_control_part_bounds (SCROLL_BAR_CONTROL_REF (bar),
+ kControlIndicatorPart, &r);
+
+ if (INTEGERP (bar->dragging) && XINT (bar->dragging) < 0)
+ XSETINT (bar->dragging, - (XINT (bar->dragging) + 1));
+
+ top = mouse_pos.v - XINT (bar->dragging) - XINT (bar->track_top);
+ top_range = XINT (bar->track_height) - XINT (bar->min_handle);
+
+ if (top < 0)
+ top = 0;
+ if (top > top_range)
+ top = top_range;
+
+ construct_scroll_bar_click (bar, scroll_bar_handle, bufp);
+ XSETINT (bufp->x, top);
+ XSETINT (bufp->y, top_range);
+ }
+ else
+ {
+ ControlPartCode part_code;
+ int unhilite_p = 0, part;
+
+ if (ch != FindControlUnderMouse (mouse_pos, win, &part_code))
+ unhilite_p = 1;
+ else
+ {
+ part = control_part_code_to_scroll_bar_part (part_code);
+
+ switch (last_scroll_bar_part)
+ {
+ case scroll_bar_above_handle:
+ case scroll_bar_below_handle:
+ if (part != scroll_bar_above_handle
+ && part != scroll_bar_below_handle)
+ unhilite_p = 1;
+ break;
+
+ case scroll_bar_up_arrow:
+ case scroll_bar_down_arrow:
+ if (part != scroll_bar_up_arrow
+ && part != scroll_bar_down_arrow)
+ unhilite_p = 1;
+ break;
+ }
+ }
+
+ if (unhilite_p)
+ HiliteControl (SCROLL_BAR_CONTROL_REF (bar), 0);
+ else if (part != last_scroll_bar_part
+ || scroll_bar_timer_event_posted_p)
+ {
+ construct_scroll_bar_click (bar, part, bufp);
+ last_scroll_bar_part = part;
+ HiliteControl (SCROLL_BAR_CONTROL_REF (bar), part_code);
+ set_scroll_bar_timer (SCROLL_BAR_CONTINUOUS_DELAY);
+ }
+ }
+}
+
+/* Update BAR->track_top, BAR->track_height, and BAR->min_handle for
+ the scroll bar BAR. This function should be called when the bounds
+ of the scroll bar is changed. */
+
+static void
+update_scroll_bar_track_info (bar)
+ struct scroll_bar *bar;
+{
+ ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
+ Rect r0, r1;
+
+ GetControlBounds (ch, &r0);
+
+ if (r0.right - r0.left >= r0.bottom - r0.top
+#ifdef MAC_OSX
+ || r0.right - r0.left < MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH
+#endif
+ )
+ {
+ XSETINT (bar->track_top, 0);
+ XSETINT (bar->track_height, 0);
+ XSETINT (bar->min_handle, 0);
+ }
+ else
+ {
+ BLOCK_INPUT;
+
+ SetControl32BitMinimum (ch, 0);
+ SetControl32BitMaximum (ch, 1 << 30);
+ SetControlViewSize (ch, 1);
+
+ /* Move the scroll bar thumb to the top. */
+ SetControl32BitValue (ch, 0);
+ get_control_part_bounds (ch, kControlIndicatorPart, &r0);
+
+ /* Move the scroll bar thumb to the bottom. */
+ SetControl32BitValue (ch, 1 << 30);
+ get_control_part_bounds (ch, kControlIndicatorPart, &r1);
+
+ UnionRect (&r0, &r1, &r0);
+ XSETINT (bar->track_top, r0.top);
+ XSETINT (bar->track_height, r0.bottom - r0.top);
+ XSETINT (bar->min_handle, r1.bottom - r1.top);
+
+ /* Don't show the scroll bar if its height is not enough to
+ display the scroll bar thumb. */
+ if (r0.bottom - r0.top > 0)
+ ShowControl (ch);
+
+ UNBLOCK_INPUT;
+ }
+}
+
+/* Set the thumb size and position of scroll bar BAR. We are currently
+ displaying PORTION out of a whole WHOLE, and our position POSITION. */
+
+void
+x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
+ struct scroll_bar *bar;
+ int portion, position, whole;
+{
+ ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
+ int value, viewsize, maximum;
+
+ if (XINT (bar->track_height) == 0)
+ return;
+
+ if (whole <= portion)
+ value = 0, viewsize = 1, maximum = 0;
+ else
+ {
+ float scale;
+
+ maximum = XINT (bar->track_height) - XINT (bar->min_handle);
+ scale = (float) maximum / (whole - portion);
+ value = position * scale + 0.5f;
+ viewsize = (int) (portion * scale + 0.5f) + XINT (bar->min_handle);
+ }
+
+ BLOCK_INPUT;
+
+ if (GetControlViewSize (ch) != viewsize
+ || GetControl32BitValue (ch) != value
+ || GetControl32BitMaximum (ch) != maximum)
+ {
+ /* Temporarily hide the scroll bar to avoid multiple redraws. */
+ SetControlVisibility (ch, false, false);
+
+ SetControl32BitMaximum (ch, maximum);
+ SetControl32BitValue (ch, value);
+ SetControlViewSize (ch, viewsize);
+
+ SetControlVisibility (ch, true, true);
+ }
+
+ UNBLOCK_INPUT;
+}
+
+#endif /* USE_TOOLKIT_SCROLL_BARS */
+
+/* Create a scroll bar control for BAR. BOUNDS and VISIBLE specifies
+ the initial geometry and visibility, respectively. The created
+ control is stored in some members of BAR. */
+
+void
+mac_create_scroll_bar (bar, bounds, visible)
+ struct scroll_bar *bar;
+ const Rect *bounds;
+ Boolean visible;
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+ ControlRef ch;
+
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
+ ch = NewControl (FRAME_MAC_WINDOW (f), bounds, "\p", visible, 0, 0, 0,
+#if TARGET_API_MAC_CARBON
+ kControlScrollBarProc,
+#else
+ scrollBarProc,
+#endif
+ (SInt32) bar);
+ SET_SCROLL_BAR_CONTROL_REF (bar, ch);
+
+ XSETINT (bar->start, 0);
+ XSETINT (bar->end, 0);
+ bar->dragging = Qnil;
+
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ update_scroll_bar_track_info (bar);
+#endif
+}
+
+/* Dispose of the scroll bar control stored in some members of
+ BAR. */
+
+void
+mac_dispose_scroll_bar (bar)
+ struct scroll_bar *bar;
+{
+#if USE_CG_DRAWING
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+
+ mac_prepare_for_quickdraw (f);
+#endif
+ DisposeControl (SCROLL_BAR_CONTROL_REF (bar));
+}
+
+/* Set bounds of the scroll bar BAR to BOUNDS. */
+
+void
+mac_set_scroll_bar_bounds (bar, bounds)
+ struct scroll_bar *bar;
+ const Rect *bounds;
+{
+ ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
+ SInt16 width, height;
+#if USE_CG_DRAWING
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+
+ mac_prepare_for_quickdraw (f);
+#endif
+
+ width = bounds->right - bounds->left;
+ height = bounds->bottom - bounds->top;
+ HideControl (ch);
+ MoveControl (ch, bounds->left, bounds->top);
+ SizeControl (ch, width, height);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ update_scroll_bar_track_info (bar);
+#else
+ if (width < height)
+ ShowControl (ch);
+#endif
+}
+
+/* Draw the scroll bar BAR. */
+
+void
+mac_redraw_scroll_bar (bar)
+ struct scroll_bar *bar;
+{
+#if USE_CG_DRAWING
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+
+ mac_prepare_for_quickdraw (f);
+#endif
+ Draw1Control (SCROLL_BAR_CONTROL_REF (bar));
+}
+
+/* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
+ is set to something other than NO_EVENT, it is enqueued.
+
+ This may be called from a signal handler, so we have to ignore GC
+ mark bits. */
+
+static void
+x_scroll_bar_handle_click (bar, part_code, er, bufp)
+ struct scroll_bar *bar;
+ ControlPartCode part_code;
+ const EventRecord *er;
+ struct input_event *bufp;
+{
+ int win_y, top_range;
+
+ if (! GC_WINDOWP (bar->window))
+ abort ();
+
+ bufp->kind = SCROLL_BAR_CLICK_EVENT;
+ bufp->frame_or_window = bar->window;
+ bufp->arg = Qnil;
+
+ bar->dragging = Qnil;
+
+ switch (part_code)
+ {
+ case kControlUpButtonPart:
+ bufp->part = scroll_bar_up_arrow;
+ break;
+ case kControlDownButtonPart:
+ bufp->part = scroll_bar_down_arrow;
+ break;
+ case kControlPageUpPart:
+ bufp->part = scroll_bar_above_handle;
+ break;
+ case kControlPageDownPart:
+ bufp->part = scroll_bar_below_handle;
+ break;
+#if TARGET_API_MAC_CARBON
+ default:
+#else
+ case kControlIndicatorPart:
+#endif
+ if (er->what == mouseDown)
+ bar->dragging = make_number (0);
+ XSETVECTOR (last_mouse_scroll_bar, bar);
+ bufp->part = scroll_bar_handle;
+ break;
+ }
+
+ win_y = XINT (bufp->y) - XINT (bar->top);
+ top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar->height));
+
+ win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
+
+ win_y -= 24;
+
+ if (! NILP (bar->dragging))
+ win_y -= XINT (bar->dragging);
+
+ if (win_y < 0)
+ win_y = 0;
+ if (win_y > top_range)
+ win_y = top_range;
+
+ XSETINT (bufp->x, win_y);
+ XSETINT (bufp->y, top_range);
+}
+
+/* Return information to the user about the current position of the mouse
+ on the scroll bar. */
+
+void
+x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
+ FRAME_PTR *fp;
+ Lisp_Object *bar_window;
+ enum scroll_bar_part *part;
+ Lisp_Object *x, *y;
+ unsigned long *time;
+{
+ struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
+ ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
+#if TARGET_API_MAC_CARBON
+ WindowRef wp = GetControlOwner (ch);
+#else
+ WindowRef wp = (*ch)->contrlOwner;
+#endif
+ Point mouse_pos;
+ struct frame *f = mac_window_to_frame (wp);
+ int win_y, top_range;
+
+#if TARGET_API_MAC_CARBON
+ GetGlobalMouse (&mouse_pos);
+ mouse_pos.h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+ mouse_pos.v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
+#else
+ SetPortWindowPort (wp);
+ GetMouse (&mouse_pos);
+#endif
+
+ win_y = mouse_pos.v - XINT (bar->top);
+ top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
+
+ win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
+
+ win_y -= 24;
+
+ if (! NILP (bar->dragging))
+ win_y -= XINT (bar->dragging);
+
+ if (win_y < 0)
+ win_y = 0;
+ if (win_y > top_range)
+ win_y = top_range;
+
+ *fp = f;
+ *bar_window = bar->window;
+
+ if (! NILP (bar->dragging))
+ *part = scroll_bar_handle;
+ else if (win_y < XINT (bar->start))
+ *part = scroll_bar_above_handle;
+ else if (win_y < XINT (bar->end) + VERTICAL_SCROLL_BAR_MIN_HANDLE)
+ *part = scroll_bar_handle;
+ else
+ *part = scroll_bar_below_handle;
+
+ XSETINT (*x, win_y);
+ XSETINT (*y, top_range);
+
+ f->mouse_moved = 0;
+ last_mouse_scroll_bar = Qnil;
+
+ *time = last_mouse_movement_time;
+}
+
+#ifndef USE_TOOLKIT_SCROLL_BARS
+/* Draw BAR's handle in the proper position.
+
+ If the handle is already drawn from START to END, don't bother
+ redrawing it, unless REBUILD is non-zero; in that case, always
+ redraw it. (REBUILD is handy for drawing the handle after expose
+ events.)
+
+ Normally, we want to constrain the start and end of the handle to
+ fit inside its rectangle, but if the user is dragging the scroll
+ bar handle, we want to let them drag it down all the way, so that
+ the bar's top is as far down as it goes; otherwise, there's no way
+ to move to the very end of the buffer. */
+
+void
+x_scroll_bar_set_handle (bar, start, end, rebuild)
+ struct scroll_bar *bar;
+ int start, end;
+ int rebuild;
+{
+ int dragging = ! NILP (bar->dragging);
+ ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
+ FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+ int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
+ int length = end - start;
+
+ /* If the display is already accurate, do nothing. */
+ if (! rebuild
+ && start == XINT (bar->start)
+ && end == XINT (bar->end))
+ return;
+
+ BLOCK_INPUT;
+
+ /* Make sure the values are reasonable, and try to preserve the
+ distance between start and end. */
+ if (start < 0)
+ start = 0;
+ else if (start > top_range)
+ start = top_range;
+ end = start + length;
+
+ if (end < start)
+ end = start;
+ else if (end > top_range && ! dragging)
+ end = top_range;
+
+ /* Store the adjusted setting in the scroll bar. */
+ XSETINT (bar->start, start);
+ XSETINT (bar->end, end);
+
+ /* Clip the end position, just for display. */
+ if (end > top_range)
+ end = top_range;
+
+ /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
+ top positions, to make sure the handle is always at least that
+ many pixels tall. */
+ end += VERTICAL_SCROLL_BAR_MIN_HANDLE;
+
+ SetControlMinimum (ch, 0);
+ /* Don't inadvertently activate deactivated scroll bars */
+ if (GetControlMaximum (ch) != -1)
+ SetControlMaximum (ch, top_range + VERTICAL_SCROLL_BAR_MIN_HANDLE
+ - (end - start));
+ SetControlValue (ch, start);
+#if TARGET_API_MAC_CARBON
+ SetControlViewSize (ch, end - start);
+#endif
+
+ UNBLOCK_INPUT;
+}
+
+/* Handle some mouse motion while someone is dragging the scroll bar.
+
+ This may be called from a signal handler, so we have to ignore GC
+ mark bits. */
+
+static void
+x_scroll_bar_note_movement (bar, y_pos, t)
+ struct scroll_bar *bar;
+ int y_pos;
+ Time t;
+{
+ FRAME_PTR f = XFRAME (XWINDOW (bar->window)->frame);
+
+ last_mouse_movement_time = t;
+
+ f->mouse_moved = 1;
+ XSETVECTOR (last_mouse_scroll_bar, bar);
+
+ /* If we're dragging the bar, display it. */
+ if (! GC_NILP (bar->dragging))
+ {
+ /* Where should the handle be now? */
+ int new_start = y_pos - 24;
+
+ if (new_start != XINT (bar->start))
+ {
+ int new_end = new_start + (XINT (bar->end) - XINT (bar->start));
+
+ x_scroll_bar_set_handle (bar, new_start, new_end, 0);
+ }
+ }
+}
+#endif /* !USE_TOOLKIT_SCROLL_BARS */
+
+\f
+/***********************************************************************
+ Tool-bars
+ ***********************************************************************/
+
+#if USE_MAC_TOOLBAR
+/* In identifiers such as function/variable names, Emacs tool bar is
+ referred to as `tool_bar', and Carbon HIToolbar as `toolbar'. */
+
+#define TOOLBAR_IDENTIFIER (CFSTR ("org.gnu.Emacs.toolbar"))
+#define TOOLBAR_ICON_ITEM_IDENTIFIER (CFSTR ("org.gnu.Emacs.toolbar.icon"))
+
+#define TOOLBAR_ITEM_COMMAND_ID_OFFSET 'Tb\0\0'
+#define TOOLBAR_ITEM_COMMAND_ID_P(id) \
+ (((id) & ~0xffff) == TOOLBAR_ITEM_COMMAND_ID_OFFSET)
+#define TOOLBAR_ITEM_COMMAND_ID_VALUE(id) \
+ ((id) - TOOLBAR_ITEM_COMMAND_ID_OFFSET)
+#define TOOLBAR_ITEM_MAKE_COMMAND_ID(value) \
+ ((value) + TOOLBAR_ITEM_COMMAND_ID_OFFSET)
+
+static OSStatus mac_handle_toolbar_command_event P_ ((EventHandlerCallRef,
+ EventRef, void *));
+
+extern Rect last_mouse_glyph;
+
+extern void mac_move_window_with_gravity P_ ((struct frame *, int,
+ short, short));
+extern void mac_get_window_origin_with_gravity P_ ((struct frame *, int,
+ short *, short *));
+extern CGImageRef mac_image_spec_to_cg_image P_ ((struct frame *,
+ Lisp_Object));
+
+static OSStatus
+mac_handle_toolbar_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus result = eventNotHandledErr;
+
+ switch (GetEventKind (event))
+ {
+ case kEventToolbarGetDefaultIdentifiers:
+ result = noErr;
+ break;
+
+ case kEventToolbarGetAllowedIdentifiers:
+ {
+ CFMutableArrayRef array;
+
+ GetEventParameter (event, kEventParamMutableArray,
+ typeCFMutableArrayRef, NULL,
+ sizeof (CFMutableArrayRef), NULL, &array);
+ CFArrayAppendValue (array, TOOLBAR_ICON_ITEM_IDENTIFIER);
+ result = noErr;
+ }
+ break;
+
+ case kEventToolbarCreateItemWithIdentifier:
+ {
+ CFStringRef identifier;
+ HIToolbarItemRef item = NULL;
+
+ GetEventParameter (event, kEventParamToolbarItemIdentifier,
+ typeCFStringRef, NULL,
+ sizeof (CFStringRef), NULL, &identifier);
+
+ if (CFStringCompare (identifier, TOOLBAR_ICON_ITEM_IDENTIFIER, 0)
+ == kCFCompareEqualTo)
+ HIToolbarItemCreate (identifier,
+ kHIToolbarItemAllowDuplicates
+ | kHIToolbarItemCantBeRemoved, &item);
+
+ if (item)
+ {
+ SetEventParameter (event, kEventParamToolbarItem,
+ typeHIToolbarItemRef,
+ sizeof (HIToolbarItemRef), &item);
+ result = noErr;
+ }
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ return result;
+}
+
+/* Create a tool bar for frame F. */
+
+static OSStatus
+mac_create_frame_tool_bar (f)
+ FRAME_PTR f;
+{
+ OSStatus err;
+ HIToolbarRef toolbar;
+
+ err = HIToolbarCreate (TOOLBAR_IDENTIFIER, kHIToolbarNoAttributes,
+ &toolbar);
+ if (err == noErr)
+ {
+ static const EventTypeSpec specs[] =
+ {{kEventClassToolbar, kEventToolbarGetDefaultIdentifiers},
+ {kEventClassToolbar, kEventToolbarGetAllowedIdentifiers},
+ {kEventClassToolbar, kEventToolbarCreateItemWithIdentifier}};
+
+ err = InstallEventHandler (HIObjectGetEventTarget (toolbar),
+ mac_handle_toolbar_event,
+ GetEventTypeCount (specs), specs,
+ f, NULL);
+ }
+
+ if (err == noErr)
+ err = HIToolbarSetDisplayMode (toolbar, kHIToolbarDisplayModeIconOnly);
+ if (err == noErr)
+ {
+ static const EventTypeSpec specs[] =
+ {{kEventClassCommand, kEventCommandProcess}};
+
+ err = InstallWindowEventHandler (FRAME_MAC_WINDOW (f),
+ mac_handle_toolbar_command_event,
+ GetEventTypeCount (specs),
+ specs, f, NULL);
+ }
+ if (err == noErr)
+ err = SetWindowToolbar (FRAME_MAC_WINDOW (f), toolbar);
+
+ if (toolbar)
+ CFRelease (toolbar);
+
+ return err;
+}
+
+/* Update the tool bar for frame F. Add new buttons and remove old. */
+
+void
+update_frame_tool_bar (f)
+ FRAME_PTR f;
+{
+ HIToolbarRef toolbar = NULL;
+ short left, top;
+ CFArrayRef old_items = NULL;
+ CFIndex old_count;
+ int i, pos, win_gravity = f->output_data.mac->toolbar_win_gravity;
+ struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+
+ BLOCK_INPUT;
+
+ GetWindowToolbar (FRAME_MAC_WINDOW (f), &toolbar);
+ if (toolbar == NULL)
+ {
+ mac_create_frame_tool_bar (f);
+ GetWindowToolbar (FRAME_MAC_WINDOW (f), &toolbar);
+ if (toolbar == NULL)
+ goto out;
+ if (win_gravity >= NorthWestGravity && win_gravity <= SouthEastGravity)
+ mac_get_window_origin_with_gravity (f, win_gravity, &left, &top);
+ }
+
+ HIToolbarCopyItems (toolbar, &old_items);
+ if (old_items == NULL)
+ goto out;
+
+ old_count = CFArrayGetCount (old_items);
+ pos = 0;
+ for (i = 0; i < f->n_tool_bar_items; ++i)
+ {
+#define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
+
+ int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
+ int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
+ int idx;
+ Lisp_Object image;
+ CGImageRef cg_image;
+ CFStringRef label;
+ HIToolbarItemRef item;
+
+ /* If image is a vector, choose the image according to the
+ button state. */
+ image = PROP (TOOL_BAR_ITEM_IMAGES);
+ if (VECTORP (image))
+ {
+ if (enabled_p)
+ idx = (selected_p
+ ? TOOL_BAR_IMAGE_ENABLED_SELECTED
+ : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
+ else
+ idx = (selected_p
+ ? TOOL_BAR_IMAGE_DISABLED_SELECTED
+ : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
+
+ xassert (ASIZE (image) >= idx);
+ image = AREF (image, idx);
+ }
+ else
+ idx = -1;
+
+ cg_image = mac_image_spec_to_cg_image (f, image);
+ /* Ignore invalid image specifications. */
+ if (cg_image == NULL)
+ continue;
+
+ label = cfstring_create_with_string (PROP (TOOL_BAR_ITEM_CAPTION));
+ if (label == NULL)
+ label = CFSTR ("");
+
+ if (pos < old_count)
+ {
+ CGImageRef old_cg_image = NULL;
+ CFStringRef old_label = NULL;
+ Boolean old_enabled_p;
+
+ item = (HIToolbarItemRef) CFArrayGetValueAtIndex (old_items, pos);
+
+ HIToolbarItemCopyImage (item, &old_cg_image);
+ if (cg_image != old_cg_image)
+ HIToolbarItemSetImage (item, cg_image);
+ CGImageRelease (old_cg_image);
+
+ HIToolbarItemCopyLabel (item, &old_label);
+ if (CFStringCompare (label, old_label, 0) != kCFCompareEqualTo)
+ HIToolbarItemSetLabel (item, label);
+ CFRelease (old_label);
+
+ old_enabled_p = HIToolbarItemIsEnabled (item);
+ if ((enabled_p || idx >= 0) != old_enabled_p)
+ HIToolbarItemSetEnabled (item, (enabled_p || idx >= 0));
+ }
+ else
+ {
+ item = NULL;
+ HIToolbarCreateItemWithIdentifier (toolbar,
+ TOOLBAR_ICON_ITEM_IDENTIFIER,
+ NULL, &item);
+ if (item)
+ {
+ HIToolbarItemSetImage (item, cg_image);
+ HIToolbarItemSetLabel (item, label);
+ HIToolbarItemSetEnabled (item, (enabled_p || idx >= 0));
+ HIToolbarAppendItem (toolbar, item);
+ CFRelease (item);
+ }
+ }
+
+ CFRelease (label);
+ if (item)
+ {
+ HIToolbarItemSetCommandID (item, TOOLBAR_ITEM_MAKE_COMMAND_ID (i));
+ pos++;
+ }
+ }
+
+ CFRelease (old_items);
+
+ while (pos < old_count)
+ HIToolbarRemoveItemAtIndex (toolbar, --old_count);
+
+ ShowHideWindowToolbar (FRAME_MAC_WINDOW (f), true,
+ !win_gravity && f == mac_focus_frame (dpyinfo));
+ /* Mac OS X 10.3 does not issue kEventWindowBoundsChanged events on
+ toolbar visibility change. */
+ mac_handle_origin_change (f);
+ if (win_gravity >= NorthWestGravity && win_gravity <= SouthEastGravity)
+ {
+ mac_move_window_with_gravity (f, win_gravity, left, top);
+ /* If the title bar is completely outside the screen, adjust the
+ position. */
+ ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
+ kWindowConstrainMoveRegardlessOfFit
+ | kWindowConstrainAllowPartial, NULL, NULL);
+ f->output_data.mac->toolbar_win_gravity = 0;
+ }
+
+ out:
+ UNBLOCK_INPUT;
+}
+
+/* Hide the tool bar on frame F. Unlike the counterpart on GTK+, it
+ doesn't deallocate the resources. */
+
+void
+free_frame_tool_bar (f)
+ FRAME_PTR f;
+{
+ if (IsWindowToolbarVisible (FRAME_MAC_WINDOW (f)))
+ {
+ struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+
+ BLOCK_INPUT;
+ ShowHideWindowToolbar (FRAME_MAC_WINDOW (f), false,
+ (NILP (find_symbol_value
+ (intern ("frame-notice-user-settings")))
+ && f == mac_focus_frame (dpyinfo)));
+ /* Mac OS X 10.3 does not issue kEventWindowBoundsChanged events
+ on toolbar visibility change. */
+ mac_handle_origin_change (f);
+ UNBLOCK_INPUT;
+ }
+}
+
+/* Report a mouse movement over toolbar to the mainstream Emacs
+ code. */
+
+static void
+mac_tool_bar_note_mouse_movement (f, event)
+ struct frame *f;
+ EventRef event;
+{
+ OSStatus err;
+ struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+ int mouse_down_p;
+ WindowRef window;
+ WindowPartCode part_code;
+ HIViewRef item_view;
+ UInt32 command_id;
+
+ mouse_down_p = (dpyinfo->grabbed
+ && f == last_mouse_frame
+ && FRAME_LIVE_P (f));
+ if (mouse_down_p)
+ return;
+
+ err = GetEventParameter (event, kEventParamWindowRef, typeWindowRef, NULL,
+ sizeof (WindowRef), NULL, &window);
+ if (err != noErr || window != FRAME_MAC_WINDOW (f))
+ return;
+
+ err = GetEventParameter (event, kEventParamWindowPartCode,
+ typeWindowPartCode, NULL,
+ sizeof (WindowPartCode), NULL, &part_code);
+ if (err != noErr || part_code != inStructure)
+ return;
+
+ err = HIViewGetViewForMouseEvent (HIViewGetRoot (window), event, &item_view);
+ /* This doesn't work on Mac OS X 10.2. On Mac OS X 10.3 and 10.4, a
+ toolbar item view seems to have the same command ID with that of
+ the toolbar item. */
+ if (err == noErr)
+ err = GetControlCommandID (item_view, &command_id);
+ if (err == noErr && TOOLBAR_ITEM_COMMAND_ID_P (command_id))
+ {
+ int i = TOOLBAR_ITEM_COMMAND_ID_VALUE (command_id);
+
+ if (i < f->n_tool_bar_items)
+ {
+ HIRect bounds;
+ HIViewRef content_view;
+
+ err = HIViewGetBounds (item_view, &bounds);
+ if (err == noErr)
+ err = HIViewFindByID (HIViewGetRoot (window),
+ kHIViewWindowContentID, &content_view);
+ if (err == noErr)
+ err = HIViewConvertRect (&bounds, item_view, content_view);
+ if (err == noErr)
+ SetRect (&last_mouse_glyph,
+ CGRectGetMinX (bounds), CGRectGetMinY (bounds),
+ CGRectGetMaxX (bounds), CGRectGetMaxY (bounds));
+
+ help_echo_object = help_echo_window = Qnil;
+ help_echo_pos = -1;
+ help_echo_string = PROP (TOOL_BAR_ITEM_HELP);
+ if (NILP (help_echo_string))
+ help_echo_string = PROP (TOOL_BAR_ITEM_CAPTION);
+ }
+ }
+}
+
+static OSStatus
+mac_handle_toolbar_command_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err, result = eventNotHandledErr;
+ struct frame *f = (struct frame *) data;
+ HICommand command;
+
+ err = GetEventParameter (event, kEventParamDirectObject,
+ typeHICommand, NULL,
+ sizeof (HICommand), NULL, &command);
+ if (err != noErr)
+ return result;
+
+ switch (GetEventKind (event))
+ {
+ case kEventCommandProcess:
+ if (!TOOLBAR_ITEM_COMMAND_ID_P (command.commandID))
+ result = CallNextEventHandler (next_handler, event);
+ else
+ {
+ int i = TOOLBAR_ITEM_COMMAND_ID_VALUE (command.commandID);
+
+ if (i < f->n_tool_bar_items
+ && !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P)))
+ {
+ Lisp_Object frame;
+ struct input_event buf;
+
+ EVENT_INIT (buf);
+
+ XSETFRAME (frame, f);
+ buf.kind = TOOL_BAR_EVENT;
+ buf.frame_or_window = frame;
+ buf.arg = frame;
+ kbd_buffer_store_event (&buf);
+
+ buf.kind = TOOL_BAR_EVENT;
+ buf.frame_or_window = frame;
+ buf.arg = PROP (TOOL_BAR_ITEM_KEY);
+ buf.modifiers = mac_event_to_emacs_modifiers (event);
+ kbd_buffer_store_event (&buf);
+
+ result = noErr;
+ }
+ }
+ break;
+
+ default:
+ abort ();
+ }
+#undef PROP
+
+ return result;
+}
+#endif /* USE_MAC_TOOLBAR */
+
+\f
+/***********************************************************************
+ Font Panel
+ ***********************************************************************/
+
+#if USE_MAC_FONT_PANEL
+/* Whether Font Panel has been shown before. The first call to font
+ panel functions (FPIsFontPanelVisible, SetFontInfoForSelection) is
+ slow. This variable is used for deferring such a call as much as
+ possible. */
+static int font_panel_shown_p = 0;
+
+extern Lisp_Object Qpanel_closed, Qselection;
+extern Lisp_Object Qfont;
+
+/* Whether the font panel is currently visible. */
+
+int
+mac_font_panel_visible_p ()
+{
+ return font_panel_shown_p && FPIsFontPanelVisible ();
+}
+
+static pascal OSStatus
+mac_handle_font_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus result, err;
+ Lisp_Object id_key;
+ int num_params;
+ const EventParamName *names;
+ const EventParamType *types;
+ static const EventParamName names_sel[] = {kEventParamATSUFontID,
+ kEventParamATSUFontSize,
+ kEventParamFMFontFamily,
+ kEventParamFMFontStyle,
+ kEventParamFMFontSize,
+ kEventParamFontColor};
+ static const EventParamType types_sel[] = {typeATSUFontID,
+ typeATSUSize,
+ typeFMFontFamily,
+ typeFMFontStyle,
+ typeFMFontSize,
+ typeFontColor};
+
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ return result;
+
+ switch (GetEventKind (event))
+ {
+ case kEventFontPanelClosed:
+ id_key = Qpanel_closed;
+ num_params = 0;
+ names = NULL;
+ types = NULL;
+ break;
+
+ case kEventFontSelection:
+ id_key = Qselection;
+ num_params = sizeof (names_sel) / sizeof (names_sel[0]);
+ names = names_sel;
+ types = types_sel;
+ break;
+ }
+
+ err = mac_store_event_ref_as_apple_event (0, 0, Qfont, id_key,
+ event, num_params,
+ names, types);
+ if (err == noErr)
+ result = noErr;
+
+ return result;
+}
+
+/* Toggle visiblity of the font panel. */
+
+OSStatus
+mac_show_hide_font_panel ()
+{
+ if (!font_panel_shown_p)
+ {
+ OSStatus err;
+
+ static const EventTypeSpec specs[] =
+ {{kEventClassFont, kEventFontPanelClosed},
+ {kEventClassFont, kEventFontSelection}};
+
+ err = InstallApplicationEventHandler (mac_handle_font_event,
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+ if (err != noErr)
+ return err;
+
+ font_panel_shown_p = 1;
+ }
+
+ return FPShowHideFontPanel ();
+}
+
+/* Set the font selected in the font panel to the one corresponding to
+ the face FACE_ID and the charcacter C in the frame F. */
+
+OSStatus
+mac_set_font_info_for_selection (f, face_id, c)
+ struct frame *f;
+ int face_id, c;
+{
+ OSStatus err;
+ EventTargetRef target = NULL;
+ XFontStruct *font = NULL;
+
+ if (!mac_font_panel_visible_p ())
+ return noErr;
+
+ if (f)
+ {
+ target = GetWindowEventTarget (FRAME_MAC_WINDOW (f));
+
+ if (FRAME_FACE_CACHE (f) && CHAR_VALID_P (c, 0))
+ {
+ struct face *face;
+
+ face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
+ face = FACE_FROM_ID (f, face_id);
+ font = face->font;
+ }
+ }
+
+ if (font == NULL)
+ err = SetFontInfoForSelection (kFontSelectionATSUIType, 0, NULL, target);
+ else
+ {
+ if (font->mac_fontnum != -1)
+ {
+ FontSelectionQDStyle qd_style;
+
+ qd_style.version = kFontSelectionQDStyleVersionZero;
+ qd_style.instance.fontFamily = font->mac_fontnum;
+ qd_style.instance.fontStyle = font->mac_fontface;
+ qd_style.size = font->mac_fontsize;
+ qd_style.hasColor = false;
+
+ err = SetFontInfoForSelection (kFontSelectionQDType,
+ 1, &qd_style, target);
+ }
+ else
+ err = SetFontInfoForSelection (kFontSelectionATSUIType,
+ 1, &font->mac_style, target);
+ }
+
+ return err;
+}
+#endif /* USE_MAC_FONT_PANEL */
+
+\f
+/************************************************************************
+ Event Handling
+ ************************************************************************/
+
+/* Non-zero means that a HELP_EVENT has been generated since Emacs
+ start. */
+
+static int any_help_event_p;
+
+/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
+static Lisp_Object last_window;
+
+static Point saved_menu_event_location;
+
+extern struct frame *pending_autoraise_frame;
+
+extern FRAME_PTR last_mouse_glyph_frame;
+
+#ifdef __STDC__
+extern int volatile input_signal_count;
+#else
+extern int input_signal_count;
+#endif
+
+extern int mac_screen_config_changed;
+
+extern Lisp_Object Vmac_emulate_three_button_mouse;
+#if TARGET_API_MAC_CARBON
+extern int mac_wheel_button_is_mouse_2;
+extern int mac_pass_command_to_system;
+extern int mac_pass_control_to_system;
+#endif /* TARGET_API_MAC_CARBON */
+extern int mac_ready_for_apple_events;
+
+extern void mac_focus_changed P_ ((int, struct mac_display_info *,
+ struct frame *, struct input_event *));
+extern int mac_get_emulated_btn P_ ((UInt32));
+extern int note_mouse_movement P_ ((FRAME_PTR, Point *));
+extern void mac_get_screen_info P_ ((struct mac_display_info *));
+
+/* The focus may have changed. Figure out if it is a real focus change,
+ by checking both FocusIn/Out and Enter/LeaveNotify events.
+
+ Returns FOCUS_IN_EVENT event in *BUFP. */
+
+static void
+x_detect_focus_change (dpyinfo, event, bufp)
+ struct mac_display_info *dpyinfo;
+ const EventRecord *event;
+ struct input_event *bufp;
+{
+ struct frame *frame;
+
+ frame = mac_window_to_frame ((WindowRef) event->message);
+ if (! frame)
+ return;
+
+ /* On Mac, this is only called from focus events, so no switch needed. */
+ mac_focus_changed ((event->modifiers & activeFlag),
+ dpyinfo, frame, bufp);
+}
+
+#if TARGET_API_MAC_CARBON
+/* Obtains the event modifiers from the event EVENTREF and then calls
+ mac_to_emacs_modifiers. */
+
+static int
+mac_event_to_emacs_modifiers (EventRef eventRef)
+{
+ UInt32 mods = 0, class;
+
+ GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
+ sizeof (UInt32), NULL, &mods);
+ class = GetEventClass (eventRef);
+ if (!NILP (Vmac_emulate_three_button_mouse)
+ && (class == kEventClassMouse || class == kEventClassCommand))
+ {
+ mods &= ~(optionKey | cmdKey);
+ }
+ return mac_to_emacs_modifiers (mods, 0);
+}
+
+/* Given an event REF, return the code to use for the mouse button
+ code in the emacs input_event. */
+
+static int
+mac_get_mouse_btn (EventRef ref)
+{
+ EventMouseButton result = kEventMouseButtonPrimary;
+ GetEventParameter (ref, kEventParamMouseButton, typeMouseButton, NULL,
+ sizeof (EventMouseButton), NULL, &result);
+ switch (result)
+ {
+ case kEventMouseButtonPrimary:
+ if (NILP (Vmac_emulate_three_button_mouse))
+ return 0;
+ else {
+ UInt32 mods = 0;
+ GetEventParameter (ref, kEventParamKeyModifiers, typeUInt32, NULL,
+ sizeof (UInt32), NULL, &mods);
+ return mac_get_emulated_btn(mods);
+ }
+ case kEventMouseButtonSecondary:
+ return mac_wheel_button_is_mouse_2 ? 2 : 1;
+ case kEventMouseButtonTertiary:
+ case 4: /* 4 is the number for the mouse wheel button */
+ return mac_wheel_button_is_mouse_2 ? 1 : 2;
+ default:
+ return 0;
+ }
+}
+
+/* Normally, ConvertEventRefToEventRecord will correctly handle all
+ events. However the click of the mouse wheel is not converted to a
+ mouseDown or mouseUp event. Likewise for dead key events. This
+ calls ConvertEventRefToEventRecord, but then checks to see if it is
+ a mouse up/down, or a dead key Carbon event that has not been
+ converted, and if so, converts it by hand (to be picked up in the
+ XTread_socket loop). */
+static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
+{
+ OSStatus err;
+ Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec);
+ EventKind action;
+
+ if (result)
+ return result;
+
+ switch (GetEventClass (eventRef))
+ {
+ case kEventClassMouse:
+ switch (GetEventKind (eventRef))
+ {
+ case kEventMouseDown:
+ eventRec->what = mouseDown;
+ result = 1;
+ break;
+
+ case kEventMouseUp:
+ eventRec->what = mouseUp;
+ result = 1;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case kEventClassKeyboard:
+ switch (GetEventKind (eventRef))
+ {
+ case kEventRawKeyDown:
+ action = keyDown;
+ goto keystroke_common;
+ case kEventRawKeyRepeat:
+ action = autoKey;
+ goto keystroke_common;
+ case kEventRawKeyUp:
+ action = keyUp;
+ keystroke_common:
+ {
+ unsigned char char_codes;
+ UInt32 key_code;
+
+ err = GetEventParameter (eventRef, kEventParamKeyMacCharCodes,
+ typeChar, NULL, sizeof (char),
+ NULL, &char_codes);
+ if (err == noErr)
+ err = GetEventParameter (eventRef, kEventParamKeyCode,
+ typeUInt32, NULL, sizeof (UInt32),
+ NULL, &key_code);
+ if (err == noErr)
+ {
+ eventRec->what = action;
+ eventRec->message = char_codes | ((key_code & 0xff) << 8);
+ result = 1;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (result)
+ {
+ /* Need where and when. */
+ UInt32 mods = 0;
+
+ GetEventParameter (eventRef, kEventParamMouseLocation, typeQDPoint,
+ NULL, sizeof (Point), NULL, &eventRec->where);
+ /* Use two step process because new event modifiers are 32-bit
+ and old are 16-bit. Currently, only loss is NumLock & Fn. */
+ GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32,
+ NULL, sizeof (UInt32), NULL, &mods);
+ eventRec->modifiers = mods;
+
+ eventRec->when = EventTimeToTicks (GetEventTime (eventRef));
+ }
+
+ return result;
+}
+#endif /* TARGET_API_MAC_CARBON */
+
+#if !TARGET_API_MAC_CARBON
+static RgnHandle mouse_region = NULL;
+
+Boolean
+mac_wait_next_event (er, sleep_time, dequeue)
+ EventRecord *er;
+ UInt32 sleep_time;
+ Boolean dequeue;
+{
+ static EventRecord er_buf = {nullEvent};
+ UInt32 target_tick, current_tick;
+ EventMask event_mask;
+
+ if (mouse_region == NULL)
+ mouse_region = NewRgn ();
+
+ event_mask = everyEvent;
+ if (!mac_ready_for_apple_events)
+ event_mask -= highLevelEventMask;
+
+ current_tick = TickCount ();
+ target_tick = current_tick + sleep_time;
+
+ if (er_buf.what == nullEvent)
+ while (!WaitNextEvent (event_mask, &er_buf,
+ target_tick - current_tick, mouse_region))
+ {
+ current_tick = TickCount ();
+ if (target_tick <= current_tick)
+ return false;
+ }
+
+ *er = er_buf;
+ if (dequeue)
+ er_buf.what = nullEvent;
+ return true;
+}
+#endif /* not TARGET_API_MAC_CARBON */
+
+#if TARGET_API_MAC_CARBON
+OSStatus
+mac_post_mouse_moved_event ()
+{
+ EventRef event = NULL;
+ OSStatus err;
+
+ err = CreateEvent (NULL, kEventClassMouse, kEventMouseMoved, 0,
+ kEventAttributeNone, &event);
+ if (err == noErr)
+ {
+ Point mouse_pos;
+
+ GetGlobalMouse (&mouse_pos);
+ err = SetEventParameter (event, kEventParamMouseLocation, typeQDPoint,
+ sizeof (Point), &mouse_pos);
+ }
+ if (err == noErr)
+ {
+ UInt32 modifiers = GetCurrentKeyModifiers ();
+
+ err = SetEventParameter (event, kEventParamKeyModifiers, typeUInt32,
+ sizeof (UInt32), &modifiers);
+ }
+ if (err == noErr)
+ err = PostEventToQueue (GetCurrentEventQueue (), event,
+ kEventPriorityStandard);
+ if (event)
+ ReleaseEvent (event);
+
+ return err;
+}
+#endif
+
+#ifdef MAC_OSX
+/* Run the current run loop in the default mode until some input
+ happens or TIMEOUT seconds passes unless it is negative. Return
+ true if timeout occurs first. */
+
+Boolean
+mac_run_loop_run_once (timeout)
+ EventTimeout timeout;
+{
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (NULL);
+#endif
+ return (CFRunLoopRunInMode (kCFRunLoopDefaultMode,
+ timeout >= 0 ? timeout : 100000, true)
+ == kCFRunLoopRunTimedOut);
+}
+#endif
+
+/* Emacs calls this whenever it wants to read an input event from the
+ user. */
+
+int
+XTread_socket (sd, expected, hold_quit)
+ int sd, expected;
+ struct input_event *hold_quit;
+{
+ struct input_event inev;
+ int count = 0;
+#if TARGET_API_MAC_CARBON
+ EventRef eventRef;
+ EventTargetRef toolbox_dispatcher;
+#endif
+ EventRecord er;
+ struct mac_display_info *dpyinfo = &one_mac_display_info;
+
+ if (interrupt_input_blocked)
+ {
+ interrupt_input_pending = 1;
+ return -1;
+ }
+
+ interrupt_input_pending = 0;
+ BLOCK_INPUT;
+
+ /* So people can tell when we have read the available input. */
+ input_signal_count++;
+
+ ++handling_signal;
+
+#if TARGET_API_MAC_CARBON
+ toolbox_dispatcher = GetEventDispatcherTarget ();
+
+ while (
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (NULL),
+#endif
+ !ReceiveNextEvent (0, NULL, kEventDurationNoWait,
+ kEventRemoveFromQueue, &eventRef))
+#else /* !TARGET_API_MAC_CARBON */
+ while (mac_wait_next_event (&er, 0, true))
+#endif /* !TARGET_API_MAC_CARBON */
+ {
+ int do_help = 0;
+ struct frame *f;
+ unsigned long timestamp;
+
+ EVENT_INIT (inev);
+ inev.kind = NO_EVENT;
+ inev.arg = Qnil;
+
+#if TARGET_API_MAC_CARBON
+ timestamp = GetEventTime (eventRef) / kEventDurationMillisecond;
+
+ if (!mac_convert_event_ref (eventRef, &er))
+ goto OTHER;
+#else /* !TARGET_API_MAC_CARBON */
+ timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
+#endif /* !TARGET_API_MAC_CARBON */
+
+ switch (er.what)
+ {
+ case mouseDown:
+ case mouseUp:
+ {
+ WindowRef window_ptr;
+ ControlPartCode part_code;
+ int tool_bar_p = 0;
+
+#if TARGET_API_MAC_CARBON
+ OSStatus err;
+
+ /* This is needed to send mouse events like aqua window
+ buttons to the correct handler. */
+ read_socket_inev = &inev;
+ err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+ read_socket_inev = NULL;
+ if (err != eventNotHandledErr)
+ break;
+#endif
+ last_mouse_glyph_frame = 0;
+
+ if (dpyinfo->grabbed && last_mouse_frame
+ && FRAME_LIVE_P (last_mouse_frame))
+ {
+ window_ptr = FRAME_MAC_WINDOW (last_mouse_frame);
+ part_code = inContent;
+ }
+ else
+ {
+ part_code = FindWindow (er.where, &window_ptr);
+ if (tip_window && window_ptr == tip_window)
+ {
+ HideWindow (tip_window);
+ part_code = FindWindow (er.where, &window_ptr);
+ }
+ }
+
+ if (er.what != mouseDown
+ && (part_code != inContent || dpyinfo->grabbed == 0))
+ break;
+
+ switch (part_code)
+ {
+ case inMenuBar:
+ f = mac_focus_frame (dpyinfo);
+ saved_menu_event_location = er.where;
+ inev.kind = MENU_BAR_ACTIVATE_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
+ break;
+
+ case inContent:
+ if (
+#if TARGET_API_MAC_CARBON
+ FrontNonFloatingWindow ()
+#else
+ FrontWindow ()
+#endif
+ != window_ptr
+ || (mac_window_to_frame (window_ptr)
+ != dpyinfo->x_focus_frame))
+ SelectWindow (window_ptr);
+ else
+ {
+ ControlPartCode control_part_code;
+ ControlRef ch;
+ Point mouse_loc;
+#ifdef MAC_OSX
+ ControlKind control_kind;
+#endif
+
+ f = mac_window_to_frame (window_ptr);
+ /* convert to local coordinates of new window */
+ mouse_loc.h = (er.where.h
+ - (f->left_pos
+ + FRAME_OUTER_TO_INNER_DIFF_X (f)));
+ mouse_loc.v = (er.where.v
+ - (f->top_pos
+ + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
+#if TARGET_API_MAC_CARBON
+ ch = FindControlUnderMouse (mouse_loc, window_ptr,
+ &control_part_code);
+#ifdef MAC_OSX
+ if (ch)
+ GetControlKind (ch, &control_kind);
+#endif
+#else
+ control_part_code = FindControl (mouse_loc, window_ptr,
+ &ch);
+#endif
+
+#if TARGET_API_MAC_CARBON
+ inev.code = mac_get_mouse_btn (eventRef);
+ inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
+#else
+ inev.code = mac_get_emulated_btn (er.modifiers);
+ inev.modifiers = mac_to_emacs_modifiers (er.modifiers, 0);
+#endif
+ XSETINT (inev.x, mouse_loc.h);
+ XSETINT (inev.y, mouse_loc.v);
+
+ if ((dpyinfo->grabbed && tracked_scroll_bar)
+ || (ch != 0
+#ifndef USE_TOOLKIT_SCROLL_BARS
+ /* control_part_code becomes kControlNoPart if
+ a progress indicator is clicked. */
+ && control_part_code != kControlNoPart
+#else /* USE_TOOLKIT_SCROLL_BARS */
+#ifdef MAC_OSX
+ && control_kind.kind == kControlKindScrollBar
+#endif /* MAC_OSX */
+#endif /* USE_TOOLKIT_SCROLL_BARS */
+ ))
+ {
+ struct scroll_bar *bar;
+
+ if (dpyinfo->grabbed && tracked_scroll_bar)
+ {
+ bar = tracked_scroll_bar;
+#ifndef USE_TOOLKIT_SCROLL_BARS
+ control_part_code = kControlIndicatorPart;
+#endif
+ }
+ else
+ bar = (struct scroll_bar *) GetControlReference (ch);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ /* Make the "Ctrl-Mouse-2 splits window" work
+ for toolkit scroll bars. */
+ if (inev.modifiers & ctrl_modifier)
+ x_scroll_bar_handle_click (bar, control_part_code,
+ &er, &inev);
+ else if (er.what == mouseDown)
+ x_scroll_bar_handle_press (bar, control_part_code,
+ mouse_loc, &inev);
+ else
+ x_scroll_bar_handle_release (bar, &inev);
+#else /* not USE_TOOLKIT_SCROLL_BARS */
+ x_scroll_bar_handle_click (bar, control_part_code,
+ &er, &inev);
+ if (er.what == mouseDown
+ && control_part_code == kControlIndicatorPart)
+ tracked_scroll_bar = bar;
+ else
+ tracked_scroll_bar = NULL;
+#endif /* not USE_TOOLKIT_SCROLL_BARS */
+ }
+ else
+ {
+ Lisp_Object window;
+ int x = mouse_loc.h;
+ int y = mouse_loc.v;
+
+ window = window_from_coordinates (f, x, y, 0, 0, 0, 1);
+ if (EQ (window, f->tool_bar_window))
+ {
+ if (er.what == mouseDown)
+ handle_tool_bar_click (f, x, y, 1, 0);
+ else
+ handle_tool_bar_click (f, x, y, 0,
+ inev.modifiers);
+ tool_bar_p = 1;
+ }
+ else
+ {
+ XSETFRAME (inev.frame_or_window, f);
+ inev.kind = MOUSE_CLICK_EVENT;
+ }
+ }
+
+ if (er.what == mouseDown)
+ {
+ dpyinfo->grabbed |= (1 << inev.code);
+ last_mouse_frame = f;
+
+ if (!tool_bar_p)
+ last_tool_bar_item = -1;
+ }
+ else
+ {
+ if ((dpyinfo->grabbed & (1 << inev.code)) == 0)
+ /* If a button is released though it was not
+ previously pressed, that would be because
+ of multi-button emulation. */
+ dpyinfo->grabbed = 0;
+ else
+ dpyinfo->grabbed &= ~(1 << inev.code);
+ }
+
+ /* Ignore any mouse motion that happened before
+ this event; any subsequent mouse-movement Emacs
+ events should reflect only motion after the
+ ButtonPress. */
+ if (f != 0)
+ f->mouse_moved = 0;
+
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ if (inev.kind == MOUSE_CLICK_EVENT
+ || (inev.kind == SCROLL_BAR_CLICK_EVENT
+ && (inev.modifiers & ctrl_modifier)))
+#endif
+ switch (er.what)
+ {
+ case mouseDown:
+ inev.modifiers |= down_modifier;
+ break;
+ case mouseUp:
+ inev.modifiers |= up_modifier;
+ break;
+ }
+ }
+ break;
+
+ case inDrag:
+#if TARGET_API_MAC_CARBON
+ case inProxyIcon:
+ if (IsWindowPathSelectClick (window_ptr, &er))
+ {
+ WindowPathSelect (window_ptr, NULL, NULL);
+ break;
+ }
+ if (part_code == inProxyIcon
+ && (TrackWindowProxyDrag (window_ptr, er.where)
+ != errUserWantsToDragWindow))
+ break;
+ DragWindow (window_ptr, er.where, NULL);
+#else /* not TARGET_API_MAC_CARBON */
+ DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
+ /* Update the frame parameters. */
+ {
+ struct frame *f = mac_window_to_frame (window_ptr);
+
+ if (f && !f->async_iconified)
+ mac_handle_origin_change (f);
+ }
+#endif /* not TARGET_API_MAC_CARBON */
+ break;
+
+ case inGoAway:
+ if (TrackGoAway (window_ptr, er.where))
+ {
+ inev.kind = DELETE_WINDOW_EVENT;
+ XSETFRAME (inev.frame_or_window,
+ mac_window_to_frame (window_ptr));
+ }
+ break;
+
+ /* window resize handling added --ben */
+ case inGrow:
+ do_grow_window (window_ptr, &er);
+ break;
+
+ /* window zoom handling added --ben */
+ case inZoomIn:
+ case inZoomOut:
+ if (TrackBox (window_ptr, er.where, part_code))
+ do_zoom_window (window_ptr, part_code);
+ break;
+
+#if USE_MAC_TOOLBAR
+ case inStructure:
+ {
+ OSStatus err;
+ HIViewRef ch;
+
+ if (FrontNonFloatingWindow () != window_ptr)
+ SelectWindow (window_ptr);
+
+ err = HIViewGetViewForMouseEvent (HIViewGetRoot (window_ptr),
+ eventRef, &ch);
+ /* This doesn't work on Mac OS X 10.2. */
+ if (err == noErr)
+ HIViewClick (ch, eventRef);
+ }
+ break;
+#endif /* USE_MAC_TOOLBAR */
+
+ default:
+ break;
+ }
+ }
+ break;
+
+#if !TARGET_API_MAC_CARBON
+ case updateEvt:
+ do_window_update ((WindowRef) er.message);
+ break;
+#endif
+
+ case osEvt:
+#if TARGET_API_MAC_CARBON
+ if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+ != eventNotHandledErr)
+ break;
+#endif
+ switch ((er.message >> 24) & 0x000000FF)
+ {
+#if USE_MAC_TSM
+ case suspendResumeMessage:
+ if (er.message & resumeFlag)
+ mac_tsm_resume ();
+ else
+ mac_tsm_suspend ();
+ break;
+#endif
+
+ case mouseMovedMessage:
+#if !TARGET_API_MAC_CARBON
+ SetRectRgn (mouse_region, er.where.h, er.where.v,
+ er.where.h + 1, er.where.v + 1);
+#endif
+ previous_help_echo_string = help_echo_string;
+ help_echo_string = Qnil;
+
+ if (dpyinfo->grabbed && last_mouse_frame
+ && FRAME_LIVE_P (last_mouse_frame))
+ f = last_mouse_frame;
+ else
+ f = dpyinfo->x_focus_frame;
+
+ if (dpyinfo->mouse_face_hidden)
+ {
+ dpyinfo->mouse_face_hidden = 0;
+ clear_mouse_face (dpyinfo);
+ }
+
+ if (f)
+ {
+ WindowRef wp = FRAME_MAC_WINDOW (f);
+ Point mouse_pos;
+
+ mouse_pos.h = (er.where.h
+ - (f->left_pos
+ + FRAME_OUTER_TO_INNER_DIFF_X (f)));
+ mouse_pos.v = (er.where.v
+ - (f->top_pos
+ + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
+ if (dpyinfo->grabbed && tracked_scroll_bar)
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ x_scroll_bar_handle_drag (wp, tracked_scroll_bar,
+ mouse_pos, &inev);
+#else /* not USE_TOOLKIT_SCROLL_BARS */
+ x_scroll_bar_note_movement (tracked_scroll_bar,
+ mouse_pos.v
+ - XINT (tracked_scroll_bar->top),
+ er.when * (1000 / 60));
+#endif /* not USE_TOOLKIT_SCROLL_BARS */
+ else
+ {
+ /* Generate SELECT_WINDOW_EVENTs when needed. */
+ if (!NILP (Vmouse_autoselect_window))
+ {
+ Lisp_Object window;
+
+ window = window_from_coordinates (f,
+ mouse_pos.h,
+ mouse_pos.v,
+ 0, 0, 0, 0);
+
+ /* Window will be selected only when it is
+ not selected now and last mouse movement
+ event was not in it. Minibuffer window
+ will be selected only when it is active. */
+ if (WINDOWP (window)
+ && !EQ (window, last_window)
+ && !EQ (window, selected_window)
+ /* For click-to-focus window managers
+ create event iff we don't leave the
+ selected frame. */
+ && (focus_follows_mouse
+ || (EQ (XWINDOW (window)->frame,
+ XWINDOW (selected_window)->frame))))
+ {
+ inev.kind = SELECT_WINDOW_EVENT;
+ inev.frame_or_window = window;
+ }
+
+ last_window=window;
+ }
+ if (!note_mouse_movement (f, &mouse_pos))
+ help_echo_string = previous_help_echo_string;
+#if USE_MAC_TOOLBAR
+ else
+ mac_tool_bar_note_mouse_movement (f, eventRef);
+#endif
+ }
+ }
+
+ /* If the contents of the global variable
+ help_echo_string has changed, generate a
+ HELP_EVENT. */
+ if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
+ do_help = 1;
+ break;
+ }
+ break;
+
+ case activateEvt:
+ {
+ WindowRef window_ptr = (WindowRef) er.message;
+ OSErr err;
+ ControlRef root_control;
+
+ if (window_ptr == tip_window)
+ {
+ HideWindow (tip_window);
+ break;
+ }
+
+ if (!is_emacs_window (window_ptr))
+ goto OTHER;
+
+ f = mac_window_to_frame (window_ptr);
+
+ if ((er.modifiers & activeFlag) != 0)
+ {
+ /* A window has been activated */
+ Point mouse_loc;
+
+ err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control);
+ if (err == noErr)
+ ActivateControl (root_control);
+
+ x_detect_focus_change (dpyinfo, &er, &inev);
+
+ mouse_loc.h = (er.where.h
+ - (f->left_pos
+ + FRAME_OUTER_TO_INNER_DIFF_X (f)));
+ mouse_loc.v = (er.where.v
+ - (f->top_pos
+ + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
+ /* Window-activated event counts as mouse movement,
+ so update things that depend on mouse position. */
+ note_mouse_movement (f, &mouse_loc);
+ }
+ else
+ {
+ /* A window has been deactivated */
+ err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control);
+ if (err == noErr)
+ DeactivateControl (root_control);
+
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ if (dpyinfo->grabbed && tracked_scroll_bar)
+ {
+ struct input_event event;
+
+ EVENT_INIT (event);
+ event.kind = NO_EVENT;
+ x_scroll_bar_handle_release (tracked_scroll_bar, &event);
+ if (event.kind != NO_EVENT)
+ {
+ event.timestamp = timestamp;
+ kbd_buffer_store_event_hold (&event, hold_quit);
+ count++;
+ }
+ }
+#endif
+ dpyinfo->grabbed = 0;
+
+ x_detect_focus_change (dpyinfo, &er, &inev);
+
+ if (f == dpyinfo->mouse_face_mouse_frame)
+ {
+ /* If we move outside the frame, then we're
+ certainly no longer on any text in the
+ frame. */
+ clear_mouse_face (dpyinfo);
+ dpyinfo->mouse_face_mouse_frame = 0;
+ }
+
+ /* Generate a nil HELP_EVENT to cancel a help-echo.
+ Do it only if there's something to cancel.
+ Otherwise, the startup message is cleared when the
+ mouse leaves the frame. */
+ if (any_help_event_p)
+ do_help = -1;
+ }
+ }
+ break;
+
+ case keyDown:
+ case keyUp:
+ case autoKey:
+ ObscureCursor ();
+
+ f = mac_focus_frame (dpyinfo);
+ XSETFRAME (inev.frame_or_window, f);
+
+ /* If mouse-highlight is an integer, input clears out mouse
+ highlighting. */
+ if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+ && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
+ {
+ clear_mouse_face (dpyinfo);
+ dpyinfo->mouse_face_hidden = 1;
+ }
+
+ {
+ UInt32 modifiers = er.modifiers, mapped_modifiers;
+ UInt32 key_code = (er.message & keyCodeMask) >> 8;
+
+#ifdef MAC_OSX
+ GetEventParameter (eventRef, kEventParamKeyModifiers,
+ typeUInt32, NULL,
+ sizeof (UInt32), NULL, &modifiers);
+#endif
+ mapped_modifiers = mac_mapped_modifiers (modifiers, key_code);
+
+#if TARGET_API_MAC_CARBON
+ if (!(mapped_modifiers
+ & ~(mac_pass_command_to_system ? cmdKey : 0)
+ & ~(mac_pass_control_to_system ? controlKey : 0)))
+ goto OTHER;
+ else
+#endif
+ if (er.what != keyUp)
+ do_keystroke (er.what, er.message & charCodeMask,
+ key_code, modifiers, timestamp, &inev);
+ }
+ break;
+
+ case kHighLevelEvent:
+ AEProcessAppleEvent (&er);
+ break;
+
+ default:
+ OTHER:
+#if TARGET_API_MAC_CARBON
+ {
+ OSStatus err;
+
+ read_socket_inev = &inev;
+ err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+ read_socket_inev = NULL;
+ }
+#endif
+ break;
+ }
+#if TARGET_API_MAC_CARBON
+ ReleaseEvent (eventRef);
+#endif
+
+ if (inev.kind != NO_EVENT)
+ {
+ inev.timestamp = timestamp;
+ kbd_buffer_store_event_hold (&inev, hold_quit);
+ count++;
+ }
+
+ if (do_help
+ && !(hold_quit && hold_quit->kind != NO_EVENT))
+ {
+ Lisp_Object frame;
+
+ if (f)
+ XSETFRAME (frame, f);
+ else
+ frame = Qnil;
+
+ if (do_help > 0)
+ {
+ any_help_event_p = 1;
+ gen_help_event (help_echo_string, frame, help_echo_window,
+ help_echo_object, help_echo_pos);
+ }
+ else
+ {
+ help_echo_string = Qnil;
+ gen_help_event (Qnil, frame, Qnil, Qnil, 0);
+ }
+ count++;
+ }
+ }
+
+ /* If the focus was just given to an autoraising frame,
+ raise it now. */
+ /* ??? This ought to be able to handle more than one such frame. */
+ if (pending_autoraise_frame)
+ {
+ x_raise_frame (pending_autoraise_frame);
+ pending_autoraise_frame = 0;
+ }
+
+ if (mac_screen_config_changed)
+ {
+ mac_get_screen_info (dpyinfo);
+ mac_screen_config_changed = 0;
+ }
+
+#if !TARGET_API_MAC_CARBON
+ /* Check which frames are still visible. We do this here because
+ there doesn't seem to be any direct notification from the Window
+ Manager that the visibility of a window has changed (at least,
+ not in all cases). */
+ {
+ Lisp_Object tail, frame;
+
+ FOR_EACH_FRAME (tail, frame)
+ {
+ struct frame *f = XFRAME (frame);
+
+ /* The tooltip has been drawn already. Avoid the
+ SET_FRAME_GARBAGED in mac_handle_visibility_change. */
+ if (EQ (frame, tip_frame))
+ continue;
+
+ if (FRAME_MAC_P (f))
+ mac_handle_visibility_change (f);
+ }
+ }
+#endif
+
+ --handling_signal;
+ UNBLOCK_INPUT;
+ return count;
+}
+
+\f
+/***********************************************************************
+ Busy cursor
+ ***********************************************************************/
+
+#if TARGET_API_MAC_CARBON
+/* Show the spinning progress indicator for the frame F. Create it if
+ it doesn't exist yet. */
+
+void
+mac_show_hourglass (f)
+ struct frame *f;
+{
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
+ if (!f->output_data.mac->hourglass_control)
+ {
+ Window w = FRAME_MAC_WINDOW (f);
+ Rect r;
+ ControlRef c;
+
+ GetWindowPortBounds (w, &r);
+ r.left = r.right - HOURGLASS_WIDTH;
+ r.bottom = r.top + HOURGLASS_HEIGHT;
+ if (CreateChasingArrowsControl (w, &r, &c) == noErr)
+ f->output_data.mac->hourglass_control = c;
+ }
+
+ if (f->output_data.mac->hourglass_control)
+ ShowControl (f->output_data.mac->hourglass_control);
+}
+
+/* Hide the spinning progress indicator for the frame F. Do nothing
+ it doesn't exist yet. */
+
+void
+mac_hide_hourglass (f)
+ struct frame *f;
+{
+ if (f->output_data.mac->hourglass_control)
+ {
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
+ HideControl (f->output_data.mac->hourglass_control);
+ }
+}
+
+/* Reposition the spinning progress indicator for the frame F. Do
+ nothing it doesn't exist yet. */
+
+void
+mac_reposition_hourglass (f)
+ struct frame *f;
+{
+ if (f->output_data.mac->hourglass_control)
+ {
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
+ MoveControl (f->output_data.mac->hourglass_control,
+ FRAME_PIXEL_WIDTH (f) - HOURGLASS_WIDTH, 0);
+ }
+}
+#endif /* TARGET_API_MAC_CARBON */
+
+\f
+/***********************************************************************
+ File selection dialog
+ ***********************************************************************/
+
+#if TARGET_API_MAC_CARBON
+extern Lisp_Object Qfile_name_history;
+
+static pascal void mac_nav_event_callback P_ ((NavEventCallbackMessage,
+ NavCBRecPtr, void *));
+
+/* The actual implementation of Fx_file_dialog. */
+
+Lisp_Object
+mac_file_dialog (prompt, dir, default_filename, mustmatch, only_dir_p)
+ Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
+{
+ Lisp_Object file = Qnil;
+ int count = SPECPDL_INDEX ();
+ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
+ char filename[MAXPATHLEN];
+ static NavEventUPP mac_nav_event_callbackUPP = NULL;
+
+ check_mac ();
+
+ GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p);
+ CHECK_STRING (prompt);
+ CHECK_STRING (dir);
+
+ /* Create the dialog with PROMPT as title, using DIR as initial
+ directory and using "*" as pattern. */
+ dir = Fexpand_file_name (dir, Qnil);
+
+ {
+ OSStatus status;
+ NavDialogCreationOptions options;
+ NavDialogRef dialogRef;
+ NavTypeListHandle fileTypes = NULL;
+ NavUserAction userAction;
+ CFStringRef message=NULL, saveName = NULL;
+
+ BLOCK_INPUT;
+ /* No need for a callback function because we are modal */
+ NavGetDefaultDialogCreationOptions(&options);
+ options.modality = kWindowModalityAppModal;
+ options.location.h = options.location.v = -1;
+ options.optionFlags = kNavDefaultNavDlogOptions;
+ options.optionFlags |= kNavAllFilesInPopup; /* All files allowed */
+ options.optionFlags |= kNavSelectAllReadableItem;
+ options.optionFlags &= ~kNavAllowMultipleFiles;
+ if (!NILP(prompt))
+ {
+ message = cfstring_create_with_string (prompt);
+ options.message = message;
+ }
+ /* Don't set the application, let it use default.
+ options.clientName = CFSTR ("Emacs");
+ */
+
+ if (mac_nav_event_callbackUPP == NULL)
+ mac_nav_event_callbackUPP = NewNavEventUPP (mac_nav_event_callback);
+
+ if (!NILP (only_dir_p))
+ status = NavCreateChooseFolderDialog(&options, mac_nav_event_callbackUPP,
+ NULL, NULL, &dialogRef);
+ else if (NILP (mustmatch))
+ {
+ /* This is a save dialog */
+ options.optionFlags |= kNavDontConfirmReplacement;
+ options.actionButtonLabel = CFSTR ("Ok");
+ options.windowTitle = CFSTR ("Enter name");
+
+ if (STRINGP (default_filename))
+ {
+ Lisp_Object utf8 = ENCODE_UTF_8 (default_filename);
+ char *begPtr = SDATA(utf8);
+ char *filePtr = begPtr + SBYTES(utf8);
+ while (filePtr != begPtr && !IS_DIRECTORY_SEP(filePtr[-1]))
+ filePtr--;
+ saveName = cfstring_create_with_utf8_cstring (filePtr);
+ options.saveFileName = saveName;
+ options.optionFlags |= kNavSelectDefaultLocation;
+ }
+ status = NavCreatePutFileDialog(&options,
+ 'TEXT', kNavGenericSignature,
+ mac_nav_event_callbackUPP, NULL,
+ &dialogRef);
+ }
+ else
+ {
+ /* This is an open dialog*/
+ status = NavCreateChooseFileDialog(&options, fileTypes,
+ mac_nav_event_callbackUPP, NULL,
+ NULL, NULL, &dialogRef);
+ }
+
+ /* Set the default location and continue*/
+ if (status == noErr)
+ {
+ Lisp_Object encoded_dir = ENCODE_FILE (dir);
+ AEDesc defLocAed;
+
+ status = AECreateDesc (TYPE_FILE_NAME, SDATA (encoded_dir),
+ SBYTES (encoded_dir), &defLocAed);
+ if (status == noErr)
+ {
+ NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed);
+ AEDisposeDesc(&defLocAed);
+ }
+ status = NavDialogRun(dialogRef);
+ }
+
+ if (saveName) CFRelease(saveName);
+ if (message) CFRelease(message);
+
+ if (status == noErr) {
+ userAction = NavDialogGetUserAction(dialogRef);
+ switch (userAction)
+ {
+ case kNavUserActionNone:
+ case kNavUserActionCancel:
+ break; /* Treat cancel like C-g */
+ case kNavUserActionOpen:
+ case kNavUserActionChoose:
+ case kNavUserActionSaveAs:
+ {
+ NavReplyRecord reply;
+ Size len;
+
+ status = NavDialogGetReply(dialogRef, &reply);
+ if (status != noErr)
+ break;
+ status = AEGetNthPtr (&reply.selection, 1, TYPE_FILE_NAME,
+ NULL, NULL, filename,
+ sizeof (filename) - 1, &len);
+ if (status == noErr)
+ {
+ len = min (len, sizeof (filename) - 1);
+ filename[len] = '\0';
+ if (reply.saveFileName)
+ {
+ /* If it was a saved file, we need to add the file name */
+ if (len && len < sizeof (filename) - 1
+ && filename[len-1] != '/')
+ filename[len++] = '/';
+ CFStringGetCString(reply.saveFileName, filename+len,
+ sizeof (filename) - len,
+#ifdef MAC_OSX
+ kCFStringEncodingUTF8
+#else
+ CFStringGetSystemEncoding ()
+#endif
+ );
+ }
+ file = DECODE_FILE (make_unibyte_string (filename,
+ strlen (filename)));
+ }
+ NavDisposeReply(&reply);
+ }
+ break;
+ }
+ NavDialogDispose(dialogRef);
+ UNBLOCK_INPUT;
+ }
+ else {
+ UNBLOCK_INPUT;
+ /* Fall back on minibuffer if there was a problem */
+ file = Fcompleting_read (prompt, intern ("read-file-name-internal"),
+ dir, mustmatch, dir, Qfile_name_history,
+ default_filename, Qnil);
+ }
+ }
+
+ UNGCPRO;
+
+ /* Make "Cancel" equivalent to C-g. */
+ if (NILP (file))
+ Fsignal (Qquit, Qnil);
+
+ return unbind_to (count, file);
+}
+
+/* Need to register some event callback function for enabling drag and
+ drop in Navigation Service dialogs. */
+static pascal void
+mac_nav_event_callback (selector, parms, data)
+ NavEventCallbackMessage selector;
+ NavCBRecPtr parms;
+ void *data;
+{
+}
+#endif
+
+\f
+/************************************************************************
+ Menu
+ ************************************************************************/
+
+#if !TARGET_API_MAC_CARBON
+#include <MacTypes.h>
+#include <Menus.h>
+#include <Quickdraw.h>
+#include <ToolUtils.h>
+#include <Fonts.h>
+#include <Controls.h>
+#include <Windows.h>
+#include <Events.h>
+#if defined (__MRC__) || (__MSL__ >= 0x6000)
+#include <ControlDefinitions.h>
+#endif
+#endif /* not TARGET_API_MAC_CARBON */
+
+extern int menu_item_selection;
+extern int popup_activated_flag;
+extern int name_is_separator P_ ((const char *));
+extern void find_and_call_menu_selection P_ ((FRAME_PTR, int, Lisp_Object,
+ void *));
+extern void set_frame_menubar P_ ((FRAME_PTR, int, int));
+
+enum mac_menu_kind { /* Menu ID range */
+ MAC_MENU_APPLE, /* 0 (Reserved by Apple) */
+ MAC_MENU_MENU_BAR, /* 1 .. 233 */
+ MAC_MENU_M_APPLE, /* 234 (== M_APPLE) */
+ MAC_MENU_POPUP, /* 235 */
+ MAC_MENU_DRIVER, /* 236 .. 255 (Reserved) */
+ MAC_MENU_MENU_BAR_SUB, /* 256 .. 16383 */
+ MAC_MENU_POPUP_SUB, /* 16384 .. 32767 */
+ MAC_MENU_END /* 32768 */
+};
+
+static const int min_menu_id[] = {0, 1, 234, 235, 236, 256, 16384, 32768};
+
+static int fill_menu P_ ((MenuRef, widget_value *, enum mac_menu_kind, int));
+static void dispose_menus P_ ((enum mac_menu_kind, int));
+
+#if !TARGET_API_MAC_CARBON
+static void
+do_apple_menu (SInt16 menu_item)
+{
+ Str255 item_name;
+ SInt16 da_driver_refnum;
+
+ if (menu_item == I_ABOUT)
+ NoteAlert (ABOUT_ALERT_ID, NULL);
+ else
+ {
+ GetMenuItemText (GetMenuRef (M_APPLE), menu_item, item_name);
+ da_driver_refnum = OpenDeskAcc (item_name);
+ }
+}
+#endif /* !TARGET_API_MAC_CARBON */
+
+/* Activate the menu bar of frame F.
+ This is called from keyboard.c when it gets the
+ MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue.
+
+ To activate the menu bar, we use the button-press event location
+ that was saved in saved_menu_event_location.
+
+ But first we recompute the menu bar contents (the whole tree).
+
+ The reason for saving the button event until here, instead of
+ passing it to the toolkit right away, is that we can safely
+ execute Lisp code. */
+
+void
+x_activate_menubar (f)
+ FRAME_PTR f;
+{
+ SInt32 menu_choice;
+ SInt16 menu_id, menu_item;
+
+ set_frame_menubar (f, 0, 1);
+ BLOCK_INPUT;
+
+ popup_activated_flag = 1;
+ menu_choice = MenuSelect (saved_menu_event_location);
+ popup_activated_flag = 0;
+ menu_id = HiWord (menu_choice);
+ menu_item = LoWord (menu_choice);
+
+#if !TARGET_API_MAC_CARBON
+ if (menu_id == min_menu_id[MAC_MENU_M_APPLE])
+ do_apple_menu (menu_item);
+ else
+#endif
+ if (menu_id)
+ {
+ MenuRef menu = GetMenuRef (menu_id);
+
+ if (menu)
+ {
+ UInt32 refcon;
+
+ GetMenuItemRefCon (menu, menu_item, &refcon);
+ find_and_call_menu_selection (f, f->menu_bar_items_used,
+ f->menu_bar_vector, (void *) refcon);
+ }
+ }
+
+ HiliteMenu (0);
+
+ UNBLOCK_INPUT;
+}
+
+#if TARGET_API_MAC_CARBON
+extern Lisp_Object Vshow_help_function;
+
+static Lisp_Object
+restore_show_help_function (old_show_help_function)
+ Lisp_Object old_show_help_function;
+{
+ Vshow_help_function = old_show_help_function;
+
+ return Qnil;
+}
+
+static pascal OSStatus
+menu_target_item_handler (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err;
+ MenuRef menu;
+ MenuItemIndex menu_item;
+ Lisp_Object help;
+ GrafPtr port;
+ int specpdl_count = SPECPDL_INDEX ();
+
+ /* Don't be bothered with the overflowed toolbar items menu. */
+ if (!popup_activated ())
+ return eventNotHandledErr;
+
+ err = GetEventParameter (event, kEventParamDirectObject, typeMenuRef,
+ NULL, sizeof (MenuRef), NULL, &menu);
+ if (err == noErr)
+ err = GetEventParameter (event, kEventParamMenuItemIndex,
+ typeMenuItemIndex, NULL,
+ sizeof (MenuItemIndex), NULL, &menu_item);
+ if (err == noErr)
+ err = GetMenuItemProperty (menu, menu_item,
+ MAC_EMACS_CREATOR_CODE, 'help',
+ sizeof (Lisp_Object), NULL, &help);
+ if (err != noErr)
+ help = Qnil;
+
+ /* Temporarily bind Vshow_help_function to Qnil because we don't
+ want tooltips during menu tracking. */
+ record_unwind_protect (restore_show_help_function, Vshow_help_function);
+ Vshow_help_function = Qnil;
+ GetPort (&port);
+ show_help_echo (help, Qnil, Qnil, Qnil, 1);
+ SetPort (port);
+ unbind_to (specpdl_count, Qnil);
+
+ return err == noErr ? noErr : eventNotHandledErr;
+}
+
+/* Showing help echo string during menu tracking. */
+
+static OSStatus
+install_menu_target_item_handler ()
+{
+ static const EventTypeSpec specs[] =
+ {{kEventClassMenu, kEventMenuTargetItem}};
+
+ return InstallApplicationEventHandler (NewEventHandlerUPP
+ (menu_target_item_handler),
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+}
+#endif /* TARGET_API_MAC_CARBON */
+
+/* Event handler function that pops down a menu on C-g. We can only pop
+ down menus if CancelMenuTracking is present (OSX 10.3 or later). */
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+static pascal OSStatus
+menu_quit_handler (nextHandler, theEvent, userData)
+ EventHandlerCallRef nextHandler;
+ EventRef theEvent;
+ void* userData;
+{
+ OSStatus err;
+ UInt32 keyCode;
+ UInt32 keyModifiers;
+
+ err = GetEventParameter (theEvent, kEventParamKeyCode,
+ typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
+
+ if (err == noErr)
+ err = GetEventParameter (theEvent, kEventParamKeyModifiers,
+ typeUInt32, NULL, sizeof(UInt32),
+ NULL, &keyModifiers);
+
+ if (err == noErr && mac_quit_char_key_p (keyModifiers, keyCode))
+ {
+ MenuRef menu = userData != 0
+ ? (MenuRef)userData : AcquireRootMenu ();
+
+ CancelMenuTracking (menu, true, 0);
+ if (!userData) ReleaseMenu (menu);
+ return noErr;
+ }
+
+ return CallNextEventHandler (nextHandler, theEvent);
+}
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
+
+/* Add event handler to all menus that belong to KIND so we can detect
+ C-g. ROOT_MENU is the root menu of the tracking session to dismiss
+ when C-g is detected. NULL means the menu bar. If
+ CancelMenuTracking isn't available, do nothing. */
+
+static void
+install_menu_quit_handler (kind, root_menu)
+ enum mac_menu_kind kind;
+ MenuRef root_menu;
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ static const EventTypeSpec typesList[] =
+ {{kEventClassKeyboard, kEventRawKeyDown}};
+ int id;
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ if (CancelMenuTracking == NULL)
+ return;
+#endif
+ for (id = min_menu_id[kind]; id < min_menu_id[kind + 1]; id++)
+ {
+ MenuRef menu = GetMenuRef (id);
+
+ if (menu == NULL)
+ break;
+ InstallMenuEventHandler (menu, menu_quit_handler,
+ GetEventTypeCount (typesList),
+ typesList, root_menu, NULL);
+ }
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
+}
+
+static Lisp_Object
+pop_down_menu (arg)
+ Lisp_Object arg;
+{
+ struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
+ FRAME_PTR f = p->pointer;
+ MenuRef menu = GetMenuRef (min_menu_id[MAC_MENU_POPUP]);
+
+ BLOCK_INPUT;
+
+ /* Must reset this manually because the button release event is not
+ passed to Emacs event loop. */
+ FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0;
+
+ /* delete all menus */
+ dispose_menus (MAC_MENU_POPUP_SUB, 0);
+ DeleteMenu (min_menu_id[MAC_MENU_POPUP]);
+ DisposeMenu (menu);
+
+ UNBLOCK_INPUT;
+
+ return Qnil;
+}
+
+/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop
+ until the menu pops down. Return the selection. */
+
+void
+create_and_show_popup_menu (f, first_wv, x, y, for_click)
+ FRAME_PTR f;
+ widget_value *first_wv;
+ int x;
+ int y;
+ int for_click;
+{
+ int result = 0;
+ MenuRef menu = NewMenu (min_menu_id[MAC_MENU_POPUP], "\p");
+ int menu_item_choice;
+ int specpdl_count = SPECPDL_INDEX ();
+
+ InsertMenu (menu, -1);
+ fill_menu (menu, first_wv->contents, MAC_MENU_POPUP_SUB,
+ min_menu_id[MAC_MENU_POPUP_SUB]);
+
+ /* Add event handler so we can detect C-g. */
+ install_menu_quit_handler (MAC_MENU_POPUP, menu);
+ install_menu_quit_handler (MAC_MENU_POPUP_SUB, menu);
+
+ record_unwind_protect (pop_down_menu, make_save_value (f, 0));
+
+ /* Adjust coordinates to be root-window-relative. */
+ x += f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+ y += f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
+
+ /* Display the menu. */
+ popup_activated_flag = 1;
+ menu_item_choice = PopUpMenuSelect (menu, y, x, 0);
+ popup_activated_flag = 0;
+
+ /* Get the refcon to find the correct item */
+ if (menu_item_choice)
+ {
+ MenuRef sel_menu = GetMenuRef (HiWord (menu_item_choice));
+
+ if (sel_menu)
+ GetMenuItemRefCon (sel_menu, LoWord (menu_item_choice),
+ (UInt32 *) &result);
+ }
+
+ unbind_to (specpdl_count, Qnil);
+
+ menu_item_selection = result;
+}
+
+static void
+add_menu_item (menu, pos, wv)
+ MenuRef menu;
+ int pos;
+ widget_value *wv;
+{
+#if TARGET_API_MAC_CARBON
+ CFStringRef item_name;
+#else
+ Str255 item_name;
+#endif
+
+ if (name_is_separator (wv->name))
+ AppendMenu (menu, "\p-");
+ else
+ {
+ AppendMenu (menu, "\pX");
+
+#if TARGET_API_MAC_CARBON
+ item_name = cfstring_create_with_utf8_cstring (wv->name);
+
+ if (wv->key != NULL)
+ {
+ CFStringRef name, key;
+
+ name = item_name;
+ key = cfstring_create_with_utf8_cstring (wv->key);
+ item_name = CFStringCreateWithFormat (NULL, NULL, CFSTR ("%@ %@"),
+ name, key);
+ CFRelease (name);
+ CFRelease (key);
+ }
+
+ SetMenuItemTextWithCFString (menu, pos, item_name);
+ CFRelease (item_name);
+
+ if (wv->enabled)
+ EnableMenuItem (menu, pos);
+ else
+ DisableMenuItem (menu, pos);
+
+ if (STRINGP (wv->help))
+ SetMenuItemProperty (menu, pos, MAC_EMACS_CREATOR_CODE, 'help',
+ sizeof (Lisp_Object), &wv->help);
+#else /* ! TARGET_API_MAC_CARBON */
+ item_name[sizeof (item_name) - 1] = '\0';
+ strncpy (item_name, wv->name, sizeof (item_name) - 1);
+ if (wv->key != NULL)
+ {
+ int len = strlen (item_name);
+
+ strncpy (item_name + len, " ", sizeof (item_name) - 1 - len);
+ len = strlen (item_name);
+ strncpy (item_name + len, wv->key, sizeof (item_name) - 1 - len);
+ }
+ c2pstr (item_name);
+ SetMenuItemText (menu, pos, item_name);
+
+ if (wv->enabled)
+ EnableItem (menu, pos);
+ else
+ DisableItem (menu, pos);
+#endif /* ! TARGET_API_MAC_CARBON */
+
+ /* Draw radio buttons and tickboxes. */
+ if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE
+ || wv->button_type == BUTTON_TYPE_RADIO))
+ SetItemMark (menu, pos, checkMark);
+ else
+ SetItemMark (menu, pos, noMark);
+
+ SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data);
+ }
+}
+
+/* Construct native Mac OS menu based on widget_value tree. */
+
+static int
+fill_menu (menu, wv, kind, submenu_id)
+ MenuRef menu;
+ widget_value *wv;
+ enum mac_menu_kind kind;
+ int submenu_id;
+{
+ int pos;
+
+ for (pos = 1; wv != NULL; wv = wv->next, pos++)
+ {
+ add_menu_item (menu, pos, wv);
+ if (wv->contents && submenu_id < min_menu_id[kind + 1])
+ {
+ MenuRef submenu = NewMenu (submenu_id, "\pX");
+
+ InsertMenu (submenu, -1);
+#if TARGET_API_MAC_CARBON
+ SetMenuItemHierarchicalMenu (menu, pos, submenu);
+#else
+ SetMenuItemHierarchicalID (menu, pos, submenu_id);
+#endif
+ submenu_id = fill_menu (submenu, wv->contents, kind, submenu_id + 1);
+ }
+ }
+
+ return submenu_id;
+}
+
+/* Fill menu bar with the items defined by WV. If DEEP_P, consider
+ the entire menu trees we supply, rather than just the menu bar item
+ names. */
+
+void
+mac_fill_menubar (wv, deep_p)
+ widget_value *wv;
+ int deep_p;
+{
+ int id, submenu_id;
+#if !TARGET_API_MAC_CARBON
+ int title_changed_p = 0;
+#endif
+
+ /* Clean up the menu bar when filled by the entire menu trees. */
+ if (deep_p)
+ {
+ dispose_menus (MAC_MENU_MENU_BAR, 0);
+ dispose_menus (MAC_MENU_MENU_BAR_SUB, 0);
+#if !TARGET_API_MAC_CARBON
+ title_changed_p = 1;
+#endif
+ }
+
+ /* Fill menu bar titles and submenus. Reuse the existing menu bar
+ titles as much as possible to minimize redraw (if !deep_p). */
+ submenu_id = min_menu_id[MAC_MENU_MENU_BAR_SUB];
+ for (id = min_menu_id[MAC_MENU_MENU_BAR];
+ wv != NULL && id < min_menu_id[MAC_MENU_MENU_BAR + 1];
+ wv = wv->next, id++)
+ {
+ OSStatus err = noErr;
+ MenuRef menu;
+#if TARGET_API_MAC_CARBON
+ CFStringRef title;
+
+ title = CFStringCreateWithCString (NULL, wv->name,
+ kCFStringEncodingMacRoman);
+#else
+ Str255 title;
+
+ strncpy (title, wv->name, 255);
+ title[255] = '\0';
+ c2pstr (title);
+#endif
+
+ menu = GetMenuRef (id);
+ if (menu)
+ {
+#if TARGET_API_MAC_CARBON
+ CFStringRef old_title;
+
+ err = CopyMenuTitleAsCFString (menu, &old_title);
+ if (err == noErr)
+ {
+ if (CFStringCompare (title, old_title, 0) != kCFCompareEqualTo)
+ {
+#ifdef MAC_OSX
+ if (id + 1 == min_menu_id[MAC_MENU_MENU_BAR + 1]
+ || GetMenuRef (id + 1) == NULL)
+ {
+ /* This is a workaround for Mac OS X 10.5 where
+ just calling SetMenuTitleWithCFString fails
+ to change the title of the last (Help) menu
+ in the menu bar. */
+ DeleteMenu (id);
+ DisposeMenu (menu);
+ menu = NULL;
+ }
+ else
+#endif /* MAC_OSX */
+ err = SetMenuTitleWithCFString (menu, title);
+ }
+ CFRelease (old_title);
+ }
+ else
+ err = SetMenuTitleWithCFString (menu, title);
+#else /* !TARGET_API_MAC_CARBON */
+ if (!EqualString (title, (*menu)->menuData, false, false))
+ {
+ DeleteMenu (id);
+ DisposeMenu (menu);
+ menu = NewMenu (id, title);
+ InsertMenu (menu, GetMenuRef (id + 1) ? id + 1 : 0);
+ title_changed_p = 1;
+ }
+#endif /* !TARGET_API_MAC_CARBON */
+ }
+
+ if (!menu)
+ {
+#if TARGET_API_MAC_CARBON
+ err = CreateNewMenu (id, 0, &menu);
+ if (err == noErr)
+ err = SetMenuTitleWithCFString (menu, title);
+#else
+ menu = NewMenu (id, title);
+#endif
+ if (err == noErr)
+ {
+ InsertMenu (menu, 0);
+#if !TARGET_API_MAC_CARBON
+ title_changed_p = 1;
+#endif
+ }
+ }
+#if TARGET_API_MAC_CARBON
+ CFRelease (title);
+#endif
+
+ if (err == noErr)
+ if (wv->contents)
+ submenu_id = fill_menu (menu, wv->contents, MAC_MENU_MENU_BAR_SUB,
+ submenu_id);
+ }
+
+ if (id < min_menu_id[MAC_MENU_MENU_BAR + 1] && GetMenuRef (id))
+ {
+ dispose_menus (MAC_MENU_MENU_BAR, id);
+#if !TARGET_API_MAC_CARBON
+ title_changed_p = 1;
+#endif
+ }
+
+#if !TARGET_API_MAC_CARBON
+ if (title_changed_p)
+ InvalMenuBar ();
+#endif
+
+ /* Add event handler so we can detect C-g. */
+ install_menu_quit_handler (MAC_MENU_MENU_BAR, NULL);
+ install_menu_quit_handler (MAC_MENU_MENU_BAR_SUB, NULL);
+}
+
+/* Dispose of menus that belong to KIND, and remove them from the menu
+ list. ID is the lower bound of menu IDs that will be processed. */
+
+static void
+dispose_menus (kind, id)
+ enum mac_menu_kind kind;
+ int id;
+{
+ for (id = max (id, min_menu_id[kind]); id < min_menu_id[kind + 1]; id++)
+ {
+ MenuRef menu = GetMenuRef (id);
+
+ if (menu == NULL)
+ break;
+ DeleteMenu (id);
+ DisposeMenu (menu);
+ }
+}
+
+static void
+init_menu_bar ()
+{
+#ifdef MAC_OSX
+ OSStatus err;
+ MenuRef menu;
+ MenuItemIndex menu_index;
+
+ err = GetIndMenuItemWithCommandID (NULL, kHICommandQuit, 1,
+ &menu, &menu_index);
+ if (err == noErr)
+ SetMenuItemCommandKey (menu, menu_index, false, 0);
+ EnableMenuCommand (NULL, kHICommandPreferences);
+ err = GetIndMenuItemWithCommandID (NULL, kHICommandPreferences, 1,
+ &menu, &menu_index);
+ if (err == noErr)
+ {
+ SetMenuItemCommandKey (menu, menu_index, false, 0);
+ InsertMenuItemTextWithCFString (menu, NULL,
+ 0, kMenuItemAttrSeparator, 0);
+ InsertMenuItemTextWithCFString (menu, CFSTR ("About Emacs"),
+ 0, 0, kHICommandAbout);
+ }
+#else /* !MAC_OSX */
+#if TARGET_API_MAC_CARBON
+ SetMenuItemCommandID (GetMenuRef (M_APPLE), I_ABOUT, kHICommandAbout);
+#endif
+#endif
+}
+
+\f
+/***********************************************************************
+ Popup Dialog
+ ***********************************************************************/
+
+#if TARGET_API_MAC_CARBON
+#define DIALOG_BUTTON_COMMAND_ID_OFFSET 'Bt\0\0'
+#define DIALOG_BUTTON_COMMAND_ID_P(id) \
+ (((id) & ~0xffff) == DIALOG_BUTTON_COMMAND_ID_OFFSET)
+#define DIALOG_BUTTON_COMMAND_ID_VALUE(id) \
+ ((id) - DIALOG_BUTTON_COMMAND_ID_OFFSET)
+#define DIALOG_BUTTON_MAKE_COMMAND_ID(value) \
+ ((value) + DIALOG_BUTTON_COMMAND_ID_OFFSET)
+
+extern EMACS_TIME timer_check P_ ((int));
+static int quit_dialog_event_loop;
+
+static pascal OSStatus
+mac_handle_dialog_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err, result = eventNotHandledErr;
+ WindowRef window = (WindowRef) data;
+
+ switch (GetEventClass (event))
+ {
+ case kEventClassCommand:
+ {
+ HICommand command;
+
+ err = GetEventParameter (event, kEventParamDirectObject,
+ typeHICommand, NULL, sizeof (HICommand),
+ NULL, &command);
+ if (err == noErr)
+ if (DIALOG_BUTTON_COMMAND_ID_P (command.commandID))
+ {
+ SetWRefCon (window, command.commandID);
+ quit_dialog_event_loop = 1;
+ break;
+ }
+
+ result = CallNextEventHandler (next_handler, event);
+ }
+ break;
+
+ case kEventClassKeyboard:
+ {
+ OSStatus result;
+ char char_code;
+
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ break;
+
+ err = GetEventParameter (event, kEventParamKeyMacCharCodes,
+ typeChar, NULL, sizeof (char),
+ NULL, &char_code);
+ if (err == noErr)
+ switch (char_code)
+ {
+ case kEscapeCharCode:
+ quit_dialog_event_loop = 1;
+ break;
+
+ default:
+ {
+ UInt32 modifiers, key_code;
+
+ err = GetEventParameter (event, kEventParamKeyModifiers,
+ typeUInt32, NULL, sizeof (UInt32),
+ NULL, &modifiers);
+ if (err == noErr)
+ err = GetEventParameter (event, kEventParamKeyCode,
+ typeUInt32, NULL, sizeof (UInt32),
+ NULL, &key_code);
+ if (err == noErr)
+ if (mac_quit_char_key_p (modifiers, key_code))
+ quit_dialog_event_loop = 1;
+ }
+ break;
+ }
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ if (quit_dialog_event_loop)
+ {
+ err = QuitEventLoop (GetCurrentEventLoop ());
+ if (err == noErr)
+ result = noErr;
+ }
+
+ return result;
+}
+
+static OSStatus
+install_dialog_event_handler (window)
+ WindowRef window;
+{
+ static const EventTypeSpec specs[] =
+ {{kEventClassCommand, kEventCommandProcess},
+ {kEventClassKeyboard, kEventRawKeyDown}};
+ static EventHandlerUPP handle_dialog_eventUPP = NULL;
+
+ if (handle_dialog_eventUPP == NULL)
+ handle_dialog_eventUPP = NewEventHandlerUPP (mac_handle_dialog_event);
+ return InstallWindowEventHandler (window, handle_dialog_eventUPP,
+ GetEventTypeCount (specs), specs,
+ window, NULL);
+}
+
+static Lisp_Object
+pop_down_dialog (arg)
+ Lisp_Object arg;
+{
+ struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
+ WindowRef window = p->pointer;
+
+ BLOCK_INPUT;
+
+ if (popup_activated_flag)
+ EndAppModalStateForWindow (window);
+ DisposeWindow (window);
+ popup_activated_flag = 0;
+
+ UNBLOCK_INPUT;
+
+ return Qnil;
+}
+
+/* Pop up the dialog for frame F defined by FIRST_WV and loop until the
+ dialog pops down.
+ menu_item_selection will be set to the selection. */
+
+void
+create_and_show_dialog (f, first_wv)
+ FRAME_PTR f;
+ widget_value *first_wv;
+{
+ OSStatus err;
+ char *dialog_name, *message;
+ int nb_buttons, first_group_count, i, result = 0;
+ widget_value *wv;
+ short buttons_height, text_height, inner_width, inner_height;
+ Rect empty_rect, *rects;
+ WindowRef window = NULL;
+ ControlRef *buttons, default_button = NULL, text;
+ int specpdl_count = SPECPDL_INDEX ();
+
+ dialog_name = first_wv->name;
+ nb_buttons = dialog_name[1] - '0';
+ first_group_count = nb_buttons - (dialog_name[4] - '0');
+
+ wv = first_wv->contents;
+ message = wv->value;
+
+ wv = wv->next;
+ SetRect (&empty_rect, 0, 0, 0, 0);
+
+ /* Create dialog window. */
+ err = CreateNewWindow (kMovableModalWindowClass,
+ kWindowStandardHandlerAttribute,
+ &empty_rect, &window);
+ if (err == noErr)
+ {
+ record_unwind_protect (pop_down_dialog, make_save_value (window, 0));
+ err = SetThemeWindowBackground (window, kThemeBrushMovableModalBackground,
+ true);
+ }
+ if (err == noErr)
+ err = SetWindowTitleWithCFString (window, (dialog_name[0] == 'Q'
+ ? CFSTR ("Question")
+ : CFSTR ("Information")));
+
+ /* Create button controls and measure their optimal bounds. */
+ if (err == noErr)
+ {
+ buttons = alloca (sizeof (ControlRef) * nb_buttons);
+ rects = alloca (sizeof (Rect) * nb_buttons);
+ for (i = 0; i < nb_buttons; i++)
+ {
+ CFStringRef label = cfstring_create_with_utf8_cstring (wv->value);
+
+ if (label == NULL)
+ err = memFullErr;
+ else
+ {
+ err = CreatePushButtonControl (window, &empty_rect,
+ label, &buttons[i]);
+ CFRelease (label);
+ }
+ if (err == noErr)
+ {
+ if (!wv->enabled)
+ {
+#ifdef MAC_OSX
+ err = DisableControl (buttons[i]);
+#else
+ err = DeactivateControl (buttons[i]);
+#endif
+ }
+ else if (default_button == NULL)
+ default_button = buttons[i];
+ }
+ if (err == noErr)
+ {
+ SInt16 unused;
+
+ rects[i] = empty_rect;
+ err = GetBestControlRect (buttons[i], &rects[i], &unused);
+ }
+ if (err == noErr)
+ {
+ UInt32 command_id;
+
+ OffsetRect (&rects[i], -rects[i].left, -rects[i].top);
+ if (rects[i].right < DIALOG_BUTTON_MIN_WIDTH)
+ rects[i].right = DIALOG_BUTTON_MIN_WIDTH;
+ else if (rects[i].right > DIALOG_MAX_INNER_WIDTH)
+ rects[i].right = DIALOG_MAX_INNER_WIDTH;
+
+ command_id = DIALOG_BUTTON_MAKE_COMMAND_ID ((int) wv->call_data);
+ err = SetControlCommandID (buttons[i], command_id);
+ }
+ if (err != noErr)
+ break;
+ wv = wv->next;
+ }
+ }
+
+ /* Layout buttons. rects[i] is set relative to the bottom-right
+ corner of the inner box. */
+ if (err == noErr)
+ {
+ short bottom, right, max_height, left_align_shift;
+
+ inner_width = DIALOG_MIN_INNER_WIDTH;
+ bottom = right = max_height = 0;
+ for (i = 0; i < nb_buttons; i++)
+ {
+ if (right - rects[i].right < - inner_width)
+ {
+ if (i != first_group_count
+ && right - rects[i].right >= - DIALOG_MAX_INNER_WIDTH)
+ inner_width = - (right - rects[i].right);
+ else
+ {
+ bottom -= max_height + DIALOG_BUTTON_BUTTON_VERTICAL_SPACE;
+ right = max_height = 0;
+ }
+ }
+ if (max_height < rects[i].bottom)
+ max_height = rects[i].bottom;
+ OffsetRect (&rects[i], right - rects[i].right,
+ bottom - rects[i].bottom);
+ right = rects[i].left - DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE;
+ if (i == first_group_count - 1)
+ right -= DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE;
+ }
+ buttons_height = - (bottom - max_height);
+
+ left_align_shift = - (inner_width + rects[nb_buttons - 1].left);
+ for (i = nb_buttons - 1; i >= first_group_count; i--)
+ {
+ if (bottom != rects[i].bottom)
+ {
+ left_align_shift = - (inner_width + rects[i].left);
+ bottom = rects[i].bottom;
+ }
+ OffsetRect (&rects[i], left_align_shift, 0);
+ }
+ }
+
+ /* Create a static text control and measure its bounds. */
+ if (err == noErr)
+ {
+ CFStringRef message_string;
+ Rect bounds;
+
+ message_string = cfstring_create_with_utf8_cstring (message);
+ if (message_string == NULL)
+ err = memFullErr;
+ else
+ {
+ ControlFontStyleRec text_style;
+
+ text_style.flags = 0;
+ SetRect (&bounds, 0, 0, inner_width, 0);
+ err = CreateStaticTextControl (window, &bounds, message_string,
+ &text_style, &text);
+ CFRelease (message_string);
+ }
+ if (err == noErr)
+ {
+ SInt16 unused;
+
+ bounds = empty_rect;
+ err = GetBestControlRect (text, &bounds, &unused);
+ }
+ if (err == noErr)
+ {
+ text_height = bounds.bottom - bounds.top;
+ if (text_height < DIALOG_TEXT_MIN_HEIGHT)
+ text_height = DIALOG_TEXT_MIN_HEIGHT;
+ }
+ }
+
+ /* Place buttons. */
+ if (err == noErr)
+ {
+ inner_height = (text_height + DIALOG_TEXT_BUTTONS_VERTICAL_SPACE
+ + buttons_height);
+
+ for (i = 0; i < nb_buttons; i++)
+ {
+ OffsetRect (&rects[i], DIALOG_LEFT_MARGIN + inner_width,
+ DIALOG_TOP_MARGIN + inner_height);
+ SetControlBounds (buttons[i], &rects[i]);
+ }
+ }
+
+ /* Place text. */
+ if (err == noErr)
+ {
+ Rect bounds;
+
+ SetRect (&bounds, DIALOG_LEFT_MARGIN, DIALOG_TOP_MARGIN,
+ DIALOG_LEFT_MARGIN + inner_width,
+ DIALOG_TOP_MARGIN + text_height);
+ SetControlBounds (text, &bounds);
+ }
+
+ /* Create the application icon at the upper-left corner. */
+ if (err == noErr)
+ {
+ ControlButtonContentInfo content;
+ ControlRef icon;
+ static const ProcessSerialNumber psn = {0, kCurrentProcess};
+#ifdef MAC_OSX
+ FSRef app_location;
+#else
+ ProcessInfoRec pinfo;
+ FSSpec app_spec;
+#endif
+ SInt16 unused;
+
+ content.contentType = kControlContentIconRef;
+#ifdef MAC_OSX
+ err = GetProcessBundleLocation (&psn, &app_location);
+ if (err == noErr)
+ err = GetIconRefFromFileInfo (&app_location, 0, NULL, 0, NULL,
+ kIconServicesNormalUsageFlag,
+ &content.u.iconRef, &unused);
+#else
+ bzero (&pinfo, sizeof (ProcessInfoRec));
+ pinfo.processInfoLength = sizeof (ProcessInfoRec);
+ pinfo.processAppSpec = &app_spec;
+ err = GetProcessInformation (&psn, &pinfo);
+ if (err == noErr)
+ err = GetIconRefFromFile (&app_spec, &content.u.iconRef, &unused);
+#endif
+ if (err == noErr)
+ {
+ Rect bounds;
+
+ SetRect (&bounds, DIALOG_ICON_LEFT_MARGIN, DIALOG_ICON_TOP_MARGIN,
+ DIALOG_ICON_LEFT_MARGIN + DIALOG_ICON_WIDTH,
+ DIALOG_ICON_TOP_MARGIN + DIALOG_ICON_HEIGHT);
+ err = CreateIconControl (window, &bounds, &content, true, &icon);
+ ReleaseIconRef (content.u.iconRef);
+ }
+ }
+
+ /* Show the dialog window and run event loop. */
+ if (err == noErr)
+ if (default_button)
+ err = SetWindowDefaultButton (window, default_button);
+ if (err == noErr)
+ err = install_dialog_event_handler (window);
+ if (err == noErr)
+ {
+ SizeWindow (window,
+ DIALOG_LEFT_MARGIN + inner_width + DIALOG_RIGHT_MARGIN,
+ DIALOG_TOP_MARGIN + inner_height + DIALOG_BOTTOM_MARGIN,
+ true);
+ err = RepositionWindow (window, FRAME_MAC_WINDOW (f),
+ kWindowAlertPositionOnParentWindow);
+ }
+ if (err == noErr)
+ {
+ SetWRefCon (window, 0);
+ ShowWindow (window);
+ BringToFront (window);
+ popup_activated_flag = 1;
+ err = BeginAppModalStateForWindow (window);
+ }
+ if (err == noErr)
+ {
+ EventTargetRef toolbox_dispatcher = GetEventDispatcherTarget ();
+
+ quit_dialog_event_loop = 0;
+ while (1)
+ {
+ EMACS_TIME next_time = timer_check (1);
+ long secs = EMACS_SECS (next_time);
+ long usecs = EMACS_USECS (next_time);
+ EventTimeout timeout;
+ EventRef event;
+
+ if (secs < 0 || (secs == 0 && usecs == 0))
+ {
+ /* Sometimes timer_check returns -1 (no timers) even if
+ there are timers. So do a timeout anyway. */
+ secs = 1;
+ usecs = 0;
+ }
+
+ timeout = (secs * kEventDurationSecond
+ + usecs * kEventDurationMicrosecond);
+ err = ReceiveNextEvent (0, NULL, timeout, kEventRemoveFromQueue,
+ &event);
+ if (err == noErr)
+ {
+ SendEventToEventTarget (event, toolbox_dispatcher);
+ ReleaseEvent (event);
+ }
+#if 0 /* defined (MAC_OSX) */
+ else if (err != eventLoopTimedOutErr)
+ {
+ if (err == eventLoopQuitErr)
+ err = noErr;
+ break;
+ }
+#else
+ /* The return value of ReceiveNextEvent seems to be
+ unreliable. Use our own global variable instead. */
+ if (quit_dialog_event_loop)
+ {
+ err = noErr;
+ break;
+ }
+#endif
+ }
+ }
+ if (err == noErr)
+ {
+ UInt32 command_id = GetWRefCon (window);
+
+ if (DIALOG_BUTTON_COMMAND_ID_P (command_id))
+ result = DIALOG_BUTTON_COMMAND_ID_VALUE (command_id);
+ }
+
+ unbind_to (specpdl_count, Qnil);
+
+ menu_item_selection = result;
+}
+#else /* not TARGET_API_MAC_CARBON */
+#define DIALOG_WINDOW_RESOURCE 130
+
+int
+mac_dialog (widget_value *wv)
+{
+ char *dialog_name;
+ char *prompt;
+ char **button_labels;
+ UInt32 *ref_cons;
+ int nb_buttons;
+ int left_count;
+ int i;
+ int dialog_width;
+ Rect rect;
+ WindowRef window_ptr;
+ ControlRef ch;
+ int left;
+ EventRecord event_record;
+ SInt16 part_code;
+ int control_part_code;
+ Point mouse;
+
+ dialog_name = wv->name;
+ nb_buttons = dialog_name[1] - '0';
+ left_count = nb_buttons - (dialog_name[4] - '0');
+ button_labels = (char **) alloca (sizeof (char *) * nb_buttons);
+ ref_cons = (UInt32 *) alloca (sizeof (UInt32) * nb_buttons);
+
+ wv = wv->contents;
+ prompt = (char *) alloca (strlen (wv->value) + 1);
+ strcpy (prompt, wv->value);
+ c2pstr (prompt);
+
+ wv = wv->next;
+ for (i = 0; i < nb_buttons; i++)
+ {
+ button_labels[i] = wv->value;
+ button_labels[i] = (char *) alloca (strlen (wv->value) + 1);
+ strcpy (button_labels[i], wv->value);
+ c2pstr (button_labels[i]);
+ ref_cons[i] = (UInt32) wv->call_data;
+ wv = wv->next;
+ }
+
+ window_ptr = GetNewCWindow (DIALOG_WINDOW_RESOURCE, NULL, (WindowRef) -1);
+
+ SetPortWindowPort (window_ptr);
+
+ TextFont (0);
+ /* Left and right margins in the dialog are 13 pixels each.*/
+ dialog_width = 14;
+ /* Calculate width of dialog box: 8 pixels on each side of the text
+ label in each button, 12 pixels between buttons. */
+ for (i = 0; i < nb_buttons; i++)
+ dialog_width += StringWidth (button_labels[i]) + 16 + 12;
+
+ if (left_count != 0 && nb_buttons - left_count != 0)
+ dialog_width += 12;
+
+ dialog_width = max (dialog_width, StringWidth (prompt) + 26);
+
+ SizeWindow (window_ptr, dialog_width, 78, 0);
+ ShowWindow (window_ptr);
+
+ SetPortWindowPort (window_ptr);
+
+ TextFont (0);
+
+ MoveTo (13, 29);
+ DrawString (prompt);
+
+ left = 13;
+ for (i = 0; i < nb_buttons; i++)
+ {
+ int button_width = StringWidth (button_labels[i]) + 16;
+ SetRect (&rect, left, 45, left + button_width, 65);
+ ch = NewControl (window_ptr, &rect, button_labels[i], 1, 0, 0, 0,
+ kControlPushButtonProc, ref_cons[i]);
+ left += button_width + 12;
+ if (i == left_count - 1)
+ left += 12;
+ }
+
+ i = 0;
+ while (!i)
+ {
+ if (WaitNextEvent (mDownMask, &event_record, 10, NULL))
+ if (event_record.what == mouseDown)
+ {
+ part_code = FindWindow (event_record.where, &window_ptr);
+ if (part_code == inContent)
+ {
+ mouse = event_record.where;
+ GlobalToLocal (&mouse);
+ control_part_code = FindControl (mouse, window_ptr, &ch);
+ if (control_part_code == kControlButtonPart)
+ if (TrackControl (ch, mouse, NULL))
+ i = GetControlReference (ch);
+ }
+ }
+ }
+
+ DisposeWindow (window_ptr);
+
+ return i;
+}
+#endif /* not TARGET_API_MAC_CARBON */
+
+\f
+/***********************************************************************
+ Selection support
+***********************************************************************/
+
+#if !TARGET_API_MAC_CARBON
+#include <Scrap.h>
+#include <Endian.h>
+#endif
+
+extern Lisp_Object Vselection_converter_alist;
+extern Lisp_Object Qmac_scrap_name, Qmac_ostype;
+
+static ScrapFlavorType get_flavor_type_from_symbol P_ ((Lisp_Object,
+ Selection));
+
+/* Get a reference to the selection corresponding to the symbol SYM.
+ The reference is set to *SEL, and it becomes NULL if there's no
+ corresponding selection. Clear the selection if CLEAR_P is
+ non-zero. */
+
+OSStatus
+mac_get_selection_from_symbol (sym, clear_p, sel)
+ Lisp_Object sym;
+ int clear_p;
+ Selection *sel;
+{
+ OSStatus err = noErr;
+ Lisp_Object str = Fget (sym, Qmac_scrap_name);
+
+ if (!STRINGP (str))
+ *sel = NULL;
+ else
+ {
+#if TARGET_API_MAC_CARBON
+#ifdef MAC_OSX
+ CFStringRef scrap_name = cfstring_create_with_string (str);
+ OptionBits options = (clear_p ? kScrapClearNamedScrap
+ : kScrapGetNamedScrap);
+
+ err = GetScrapByName (scrap_name, options, sel);
+ CFRelease (scrap_name);
+#else /* !MAC_OSX */
+ if (clear_p)
+ err = ClearCurrentScrap ();
+ if (err == noErr)
+ err = GetCurrentScrap (sel);
+#endif /* !MAC_OSX */
+#else /* !TARGET_API_MAC_CARBON */
+ if (clear_p)
+ err = ZeroScrap ();
+ if (err == noErr)
+ *sel = 1;
+#endif /* !TARGET_API_MAC_CARBON */
+ }
+
+ return err;
+}
+
+/* Get a scrap flavor type from the symbol SYM. Return 0 if no
+ corresponding flavor type. If SEL is non-zero, the return value is
+ non-zero only when the SEL has the flavor type. */
+
+static ScrapFlavorType
+get_flavor_type_from_symbol (sym, sel)
+ Lisp_Object sym;
+ Selection sel;
+{
+ Lisp_Object str = Fget (sym, Qmac_ostype);
+ ScrapFlavorType flavor_type;
+
+ if (STRINGP (str) && SBYTES (str) == 4)
+ flavor_type = EndianU32_BtoN (*((UInt32 *) SDATA (str)));
+ else
+ flavor_type = 0;
+
+ if (flavor_type && sel)
+ {
+#if TARGET_API_MAC_CARBON
+ OSStatus err;
+ ScrapFlavorFlags flags;
+
+ err = GetScrapFlavorFlags (sel, flavor_type, &flags);
+ if (err != noErr)
+ flavor_type = 0;
+#else /* !TARGET_API_MAC_CARBON */
+ SInt32 size, offset;
+
+ size = GetScrap (NULL, flavor_type, &offset);
+ if (size < 0)
+ flavor_type = 0;
+#endif /* !TARGET_API_MAC_CARBON */
+ }
+
+ return flavor_type;
+}
+
+/* Check if the symbol SYM has a corresponding selection target type. */
+
+int
+mac_valid_selection_target_p (sym)
+ Lisp_Object sym;
+{
+ return get_flavor_type_from_symbol (sym, 0) != 0;
+}
+
+/* Clear the selection whose reference is *SEL. */
+
+OSStatus
+mac_clear_selection (sel)
+ Selection *sel;
+{
+#if TARGET_API_MAC_CARBON
+#ifdef MAC_OSX
+ return ClearScrap (sel);
+#else
+ OSStatus err;
+
+ err = ClearCurrentScrap ();
+ if (err == noErr)
+ err = GetCurrentScrap (sel);
+ return err;
+#endif
+#else /* !TARGET_API_MAC_CARBON */
+ return ZeroScrap ();
+#endif /* !TARGET_API_MAC_CARBON */
+}
+
+/* Get ownership information for SEL. Emacs can detect a change of
+ the ownership by comparing saved and current values of the
+ ownership information. */
+
+Lisp_Object
+mac_get_selection_ownership_info (sel)
+ Selection sel;
+{
+#if TARGET_API_MAC_CARBON
+ return long_to_cons ((unsigned long) sel);
+#else /* !TARGET_API_MAC_CARBON */
+ ScrapStuffPtr scrap_info = InfoScrap ();
+
+ return make_number (scrap_info->scrapCount);
+#endif /* !TARGET_API_MAC_CARBON */
+}
+
+/* Return non-zero if VALUE is a valid selection value for TARGET. */
+
+int
+mac_valid_selection_value_p (value, target)
+ Lisp_Object value, target;
+{
+ return STRINGP (value);
+}
+
+/* Put Lisp object VALUE to the selection SEL. The target type is
+ specified by TARGET. */
+
+OSStatus
+mac_put_selection_value (sel, target, value)
+ Selection sel;
+ Lisp_Object target, value;
+{
+ ScrapFlavorType flavor_type = get_flavor_type_from_symbol (target, 0);
+
+ if (flavor_type == 0 || !STRINGP (value))
+ return noTypeErr;
+
+#if TARGET_API_MAC_CARBON
+ return PutScrapFlavor (sel, flavor_type, kScrapFlavorMaskNone,
+ SBYTES (value), SDATA (value));
+#else /* !TARGET_API_MAC_CARBON */
+ return PutScrap (SBYTES (value), flavor_type, SDATA (value));
+#endif /* !TARGET_API_MAC_CARBON */
+}
+
+/* Check if data for the target type TARGET is available in SEL. */
+
+int
+mac_selection_has_target_p (sel, target)
+ Selection sel;
+ Lisp_Object target;
+{
+ return get_flavor_type_from_symbol (target, sel) != 0;
+}
+
+/* Get data for the target type TARGET from SEL and create a Lisp
+ string. Return nil if failed to get data. */
+
+Lisp_Object
+mac_get_selection_value (sel, target)
+ Selection sel;
+ Lisp_Object target;
+{
+ OSStatus err;
+ Lisp_Object result = Qnil;
+ ScrapFlavorType flavor_type = get_flavor_type_from_symbol (target, sel);
+#if TARGET_API_MAC_CARBON
+ Size size;
+
+ if (flavor_type)
+ {
+ err = GetScrapFlavorSize (sel, flavor_type, &size);
+ if (err == noErr)
+ {
+ do
+ {
+ result = make_uninit_string (size);
+ err = GetScrapFlavorData (sel, flavor_type,
+ &size, SDATA (result));
+ if (err != noErr)
+ result = Qnil;
+ else if (size < SBYTES (result))
+ result = make_unibyte_string (SDATA (result), size);
+ }
+ while (STRINGP (result) && size > SBYTES (result));
+ }
+ }
+#else
+ Handle handle;
+ SInt32 size, offset;
+
+ if (flavor_type)
+ size = GetScrap (NULL, flavor_type, &offset);
+ if (size >= 0)
+ {
+ handle = NewHandle (size);
+ HLock (handle);
+ size = GetScrap (handle, flavor_type, &offset);
+ if (size >= 0)
+ result = make_unibyte_string (*handle, size);
+ DisposeHandle (handle);
+ }
+#endif
+
+ return result;
+}
+
+/* Get the list of target types in SEL. The return value is a list of
+ target type symbols possibly followed by scrap flavor type
+ strings. */
+
+Lisp_Object
+mac_get_selection_target_list (sel)
+ Selection sel;
+{
+ Lisp_Object result = Qnil, rest, target;
+#if TARGET_API_MAC_CARBON
+ OSStatus err;
+ UInt32 count, i, type;
+ ScrapFlavorInfo *flavor_info = NULL;
+ Lisp_Object strings = Qnil;
+
+ err = GetScrapFlavorCount (sel, &count);
+ if (err == noErr)
+ flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count);
+ err = GetScrapFlavorInfoList (sel, &count, flavor_info);
+ if (err != noErr)
+ {
+ xfree (flavor_info);
+ flavor_info = NULL;
+ }
+ if (flavor_info == NULL)
+ count = 0;
+#endif
+ for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest))
+ {
+ ScrapFlavorType flavor_type = 0;
+
+ if (CONSP (XCAR (rest))
+ && (target = XCAR (XCAR (rest)),
+ SYMBOLP (target))
+ && (flavor_type = get_flavor_type_from_symbol (target, sel)))
+ {
+ result = Fcons (target, result);
+#if TARGET_API_MAC_CARBON
+ for (i = 0; i < count; i++)
+ if (flavor_info[i].flavorType == flavor_type)
+ {
+ flavor_info[i].flavorType = 0;
+ break;
+ }
+#endif
+ }
+ }
+#if TARGET_API_MAC_CARBON
+ if (flavor_info)
+ {
+ for (i = 0; i < count; i++)
+ if (flavor_info[i].flavorType)
+ {
+ type = EndianU32_NtoB (flavor_info[i].flavorType);
+ strings = Fcons (make_unibyte_string ((char *) &type, 4), strings);
+ }
+ result = nconc2 (result, strings);
+ xfree (flavor_info);
+ }
+#endif
+
+ return result;
+}
+
+\f
+/***********************************************************************
+ Apple event support
+***********************************************************************/
+
+extern pascal OSErr mac_handle_apple_event P_ ((const AppleEvent *,
+ AppleEvent *, SInt32));
+extern void cleanup_all_suspended_apple_events P_ ((void));
+
+void
+init_apple_event_handler ()
+{
+ OSErr err;
+ long result;
+
+ /* Make sure we have Apple events before starting. */
+ err = Gestalt (gestaltAppleEventsAttr, &result);
+ if (err != noErr)
+ abort ();
+
+ if (!(result & (1 << gestaltAppleEventsPresent)))
+ abort ();
+
+ err = AEInstallEventHandler (typeWildCard, typeWildCard,
+#if TARGET_API_MAC_CARBON
+ NewAEEventHandlerUPP (mac_handle_apple_event),
+#else
+ NewAEEventHandlerProc (mac_handle_apple_event),
+#endif
+ 0L, false);
+ if (err != noErr)
+ abort ();
+
+ atexit (cleanup_all_suspended_apple_events);
+}
+
+\f
+/***********************************************************************
+ Drag and drop support
+***********************************************************************/
+
+#if TARGET_API_MAC_CARBON
+extern Lisp_Object Vmac_dnd_known_types;
+
+static pascal OSErr mac_do_track_drag P_ ((DragTrackingMessage, WindowRef,
+ void *, DragRef));
+static pascal OSErr mac_do_receive_drag P_ ((WindowRef, void *, DragRef));
+static DragTrackingHandlerUPP mac_do_track_dragUPP = NULL;
+static DragReceiveHandlerUPP mac_do_receive_dragUPP = NULL;
+
+static OSErr
+create_apple_event_from_drag_ref (drag, num_types, types, result)
+ DragRef drag;
+ UInt32 num_types;
+ const FlavorType *types;
+ AppleEvent *result;
+{
+ OSErr err;
+ UInt16 num_items;
+ AppleEvent items;
+ long index;
+ char *buf = NULL;
+
+ err = CountDragItems (drag, &num_items);
+ if (err != noErr)
+ return err;
+ err = AECreateList (NULL, 0, false, &items);
+ if (err != noErr)
+ return err;
+
+ for (index = 1; index <= num_items; index++)
+ {
+ ItemReference item;
+ DescType desc_type = typeNull;
+ Size size;
+
+ err = GetDragItemReferenceNumber (drag, index, &item);
+ if (err == noErr)
+ {
+ int i;
+
+ for (i = 0; i < num_types; i++)
+ {
+ err = GetFlavorDataSize (drag, item, types[i], &size);
+ if (err == noErr)
+ {
+ buf = xrealloc (buf, size);
+ err = GetFlavorData (drag, item, types[i], buf, &size, 0);
+ }
+ if (err == noErr)
+ {
+ desc_type = types[i];
+ break;
+ }
+ }
+ }
+ err = AEPutPtr (&items, index, desc_type,
+ desc_type != typeNull ? buf : NULL,
+ desc_type != typeNull ? size : 0);
+ if (err != noErr)
+ break;
+ }
+ if (buf)
+ xfree (buf);
+
+ if (err == noErr)
+ {
+ err = create_apple_event (0, 0, result); /* Dummy class and ID. */
+ if (err == noErr)
+ err = AEPutParamDesc (result, keyDirectObject, &items);
+ if (err != noErr)
+ AEDisposeDesc (result);
+ }
+
+ AEDisposeDesc (&items);
+
+ return err;
+}
+
+static void
+mac_store_drag_event (window, mouse_pos, modifiers, desc)
+ WindowRef window;
+ Point mouse_pos;
+ SInt16 modifiers;
+ const AEDesc *desc;
+{
+ struct input_event buf;
+
+ EVENT_INIT (buf);
+
+ buf.kind = DRAG_N_DROP_EVENT;
+ buf.modifiers = mac_to_emacs_modifiers (modifiers, 0);
+ buf.timestamp = TickCount () * (1000 / 60);
+ XSETINT (buf.x, mouse_pos.h);
+ XSETINT (buf.y, mouse_pos.v);
+ XSETFRAME (buf.frame_or_window, mac_window_to_frame (window));
+ buf.arg = mac_aedesc_to_lisp (desc);
+ kbd_buffer_store_event (&buf);
+}
+
+static pascal OSErr
+mac_do_track_drag (message, window, refcon, drag)
+ DragTrackingMessage message;
+ WindowRef window;
+ void *refcon;
+ DragRef drag;
+{
+ OSErr err = noErr;
+ static int can_accept;
+ UInt16 num_items, index;
+
+ if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
+ return dragNotAcceptedErr;
+
+ switch (message)
+ {
+ case kDragTrackingEnterHandler:
+ err = CountDragItems (drag, &num_items);
+ if (err != noErr)
+ break;
+ can_accept = 0;
+ for (index = 1; index <= num_items; index++)
+ {
+ ItemReference item;
+ FlavorFlags flags;
+ Lisp_Object rest;
+
+ err = GetDragItemReferenceNumber (drag, index, &item);
+ if (err != noErr)
+ continue;
+ for (rest = Vmac_dnd_known_types; CONSP (rest); rest = XCDR (rest))
+ {
+ Lisp_Object str;
+ FlavorType type;
+
+ str = XCAR (rest);
+ if (!(STRINGP (str) && SBYTES (str) == 4))
+ continue;
+ type = EndianU32_BtoN (*((UInt32 *) SDATA (str)));
+
+ err = GetFlavorFlags (drag, item, type, &flags);
+ if (err == noErr)
+ {
+ can_accept = 1;
+ break;
+ }
+ }
+ }
+ break;
+
+ case kDragTrackingEnterWindow:
+ if (can_accept)
+ {
+ RgnHandle hilite_rgn = NewRgn ();
+
+ if (hilite_rgn)
+ {
+ Rect r;
+
+ GetWindowPortBounds (window, &r);
+ OffsetRect (&r, -r.left, -r.top);
+ RectRgn (hilite_rgn, &r);
+ ShowDragHilite (drag, hilite_rgn, true);
+ DisposeRgn (hilite_rgn);
+ }
+ SetThemeCursor (kThemeCopyArrowCursor);
+ }
+ break;
+
+ case kDragTrackingInWindow:
+ break;
+
+ case kDragTrackingLeaveWindow:
+ if (can_accept)
+ {
+ HideDragHilite (drag);
+ SetThemeCursor (kThemeArrowCursor);
+ }
+ break;
+
+ case kDragTrackingLeaveHandler:
+ break;
+ }
+
+ if (err != noErr)
+ return dragNotAcceptedErr;
+ return noErr;
+}
+
+static pascal OSErr
+mac_do_receive_drag (window, refcon, drag)
+ WindowRef window;
+ void *refcon;
+ DragRef drag;
+{
+ OSErr err;
+ int num_types, i;
+ Lisp_Object rest, str;
+ FlavorType *types;
+ AppleEvent apple_event;
+ Point mouse_pos;
+ SInt16 modifiers;
+
+ if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
+ return dragNotAcceptedErr;
+
+ num_types = 0;
+ for (rest = Vmac_dnd_known_types; CONSP (rest); rest = XCDR (rest))
+ {
+ str = XCAR (rest);
+ if (STRINGP (str) && SBYTES (str) == 4)
+ num_types++;
+ }
+
+ types = xmalloc (sizeof (FlavorType) * num_types);
+ i = 0;
+ for (rest = Vmac_dnd_known_types; CONSP (rest); rest = XCDR (rest))
+ {
+ str = XCAR (rest);
+ if (STRINGP (str) && SBYTES (str) == 4)
+ types[i++] = EndianU32_BtoN (*((UInt32 *) SDATA (str)));
+ }
+
+ err = create_apple_event_from_drag_ref (drag, num_types, types,
+ &apple_event);
+ xfree (types);
+
+ if (err == noErr)
+ err = GetDragMouse (drag, &mouse_pos, NULL);
+ if (err == noErr)
+ {
+ GlobalToLocal (&mouse_pos);
+ err = GetDragModifiers (drag, NULL, NULL, &modifiers);
+ }
+ if (err == noErr)
+ {
+ UInt32 key_modifiers = modifiers;
+
+ err = AEPutParamPtr (&apple_event, kEventParamKeyModifiers,
+ typeUInt32, &key_modifiers, sizeof (UInt32));
+ }
+
+ if (err == noErr)
+ {
+ mac_store_drag_event (window, mouse_pos, 0, &apple_event);
+ AEDisposeDesc (&apple_event);
+ mac_wakeup_from_rne ();
+ return noErr;
+ }
+ else
+ return dragNotAcceptedErr;
+}
+#endif /* TARGET_API_MAC_CARBON */
+
+static OSErr
+install_drag_handler (window)
+ WindowRef window;
+{
+ OSErr err = noErr;
+
+#if TARGET_API_MAC_CARBON
+ if (mac_do_track_dragUPP == NULL)
+ mac_do_track_dragUPP = NewDragTrackingHandlerUPP (mac_do_track_drag);
+ if (mac_do_receive_dragUPP == NULL)
+ mac_do_receive_dragUPP = NewDragReceiveHandlerUPP (mac_do_receive_drag);
+
+ err = InstallTrackingHandler (mac_do_track_dragUPP, window, NULL);
+ if (err == noErr)
+ err = InstallReceiveHandler (mac_do_receive_dragUPP, window, NULL);
+#endif
+
+ return err;
+}
+
+static void
+remove_drag_handler (window)
+ WindowRef window;
+{
+#if TARGET_API_MAC_CARBON
+ if (mac_do_track_dragUPP)
+ RemoveTrackingHandler (mac_do_track_dragUPP, window);
+ if (mac_do_receive_dragUPP)
+ RemoveReceiveHandler (mac_do_receive_dragUPP, window);
+#endif
+}
+
+#if TARGET_API_MAC_CARBON
+/* Return default value for mac-dnd-known-types. */
+
+Lisp_Object
+mac_dnd_default_known_types ()
+{
+ Lisp_Object result = list4 (build_string ("hfs "), build_string ("utxt"),
+ build_string ("TEXT"), build_string ("TIFF"));
+
+#ifdef MAC_OSX
+ result = Fcons (build_string ("furl"), result);
+#endif
+
+ return result;
+}
+#endif
+
+\f
+/***********************************************************************
+ Services menu support
+***********************************************************************/
+
+#ifdef MAC_OSX
+extern Lisp_Object Qservice, Qpaste, Qperform;
+extern Lisp_Object Vmac_service_selection;
+
+static OSStatus
+mac_store_service_event (event)
+ EventRef event;
+{
+ OSStatus err;
+ Lisp_Object id_key;
+ int num_params;
+ const EventParamName *names;
+ const EventParamType *types;
+ static const EventParamName names_pfm[] =
+ {kEventParamServiceMessageName, kEventParamServiceUserData};
+ static const EventParamType types_pfm[] =
+ {typeCFStringRef, typeCFStringRef};
+
+ switch (GetEventKind (event))
+ {
+ case kEventServicePaste:
+ id_key = Qpaste;
+ num_params = 0;
+ names = NULL;
+ types = NULL;
+ break;
+
+ case kEventServicePerform:
+ id_key = Qperform;
+ num_params = sizeof (names_pfm) / sizeof (names_pfm[0]);
+ names = names_pfm;
+ types = types_pfm;
+ break;
+
+ default:
+ abort ();
+ }
+
+ err = mac_store_event_ref_as_apple_event (0, 0, Qservice, id_key,
+ event, num_params,
+ names, types);
+
+ return err;
+}
+
+static OSStatus
+copy_scrap_flavor_data (from_scrap, to_scrap, flavor_type)
+ ScrapRef from_scrap, to_scrap;
+ ScrapFlavorType flavor_type;
+{
+ OSStatus err;
+ Size size, size_allocated;
+ char *buf = NULL;
+
+ err = GetScrapFlavorSize (from_scrap, flavor_type, &size);
+ if (err == noErr)
+ buf = xmalloc (size);
+ while (buf)
+ {
+ size_allocated = size;
+ err = GetScrapFlavorData (from_scrap, flavor_type, &size, buf);
+ if (err != noErr)
+ {
+ xfree (buf);
+ buf = NULL;
+ }
+ else if (size_allocated < size)
+ buf = xrealloc (buf, size);
+ else
+ break;
+ }
+ if (err == noErr)
+ {
+ if (buf == NULL)
+ err = memFullErr;
+ else
+ {
+ err = PutScrapFlavor (to_scrap, flavor_type, kScrapFlavorMaskNone,
+ size, buf);
+ xfree (buf);
+ }
+ }
+
+ return err;
+}
+
+static OSStatus
+mac_handle_service_event (call_ref, event, data)
+ EventHandlerCallRef call_ref;
+ EventRef event;
+ void *data;
+{
+ OSStatus err = noErr;
+ ScrapRef cur_scrap, specific_scrap;
+ UInt32 event_kind = GetEventKind (event);
+ CFMutableArrayRef copy_types, paste_types;
+ CFStringRef type;
+ Lisp_Object rest;
+ ScrapFlavorType flavor_type;
+
+ /* Check if Vmac_service_selection is a valid selection that has a
+ corresponding scrap. */
+ if (!SYMBOLP (Vmac_service_selection))
+ err = eventNotHandledErr;
+ else
+ err = mac_get_selection_from_symbol (Vmac_service_selection, 0, &cur_scrap);
+ if (!(err == noErr && cur_scrap))
+ return eventNotHandledErr;
+
+ switch (event_kind)
+ {
+ case kEventServiceGetTypes:
+ /* Set paste types. */
+ err = GetEventParameter (event, kEventParamServicePasteTypes,
+ typeCFMutableArrayRef, NULL,
+ sizeof (CFMutableArrayRef), NULL,
+ &paste_types);
+ if (err != noErr)
+ break;
+
+ for (rest = Vselection_converter_alist; CONSP (rest);
+ rest = XCDR (rest))
+ if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))
+ && (flavor_type =
+ get_flavor_type_from_symbol (XCAR (XCAR (rest)), 0)))
+ {
+ type = CreateTypeStringWithOSType (flavor_type);
+ if (type)
+ {
+ CFArrayAppendValue (paste_types, type);
+ CFRelease (type);
+ }
+ }
+
+ /* Set copy types. */
+ err = GetEventParameter (event, kEventParamServiceCopyTypes,
+ typeCFMutableArrayRef, NULL,
+ sizeof (CFMutableArrayRef), NULL,
+ ©_types);
+ if (err != noErr)
+ break;
+
+ if (NILP (Fx_selection_owner_p (Vmac_service_selection)))
+ break;
+ else
+ goto copy_all_flavors;
+
+ case kEventServiceCopy:
+ err = GetEventParameter (event, kEventParamScrapRef,
+ typeScrapRef, NULL,
+ sizeof (ScrapRef), NULL, &specific_scrap);
+ if (err != noErr
+ || NILP (Fx_selection_owner_p (Vmac_service_selection)))
+ {
+ err = eventNotHandledErr;
+ break;
+ }
+
+ copy_all_flavors:
+ {
+ UInt32 count, i;
+ ScrapFlavorInfo *flavor_info = NULL;
+ ScrapFlavorFlags flags;
+
+ err = GetScrapFlavorCount (cur_scrap, &count);
+ if (err == noErr)
+ flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count);
+ err = GetScrapFlavorInfoList (cur_scrap, &count, flavor_info);
+ if (err != noErr)
+ {
+ xfree (flavor_info);
+ flavor_info = NULL;
+ }
+ if (flavor_info == NULL)
+ break;
+
+ for (i = 0; i < count; i++)
+ {
+ flavor_type = flavor_info[i].flavorType;
+ err = GetScrapFlavorFlags (cur_scrap, flavor_type, &flags);
+ if (err == noErr && !(flags & kScrapFlavorMaskSenderOnly))
+ {
+ if (event_kind == kEventServiceCopy)
+ err = copy_scrap_flavor_data (cur_scrap, specific_scrap,
+ flavor_type);
+ else /* event_kind == kEventServiceGetTypes */
+ {
+ type = CreateTypeStringWithOSType (flavor_type);
+ if (type)
+ {
+ CFArrayAppendValue (copy_types, type);
+ CFRelease (type);
+ }
+ }
+ }
+ }
+ xfree (flavor_info);
+ }
+ break;
+
+ case kEventServicePaste:
+ case kEventServicePerform:
+ {
+ int data_exists_p = 0;
+
+ err = GetEventParameter (event, kEventParamScrapRef, typeScrapRef,
+ NULL, sizeof (ScrapRef), NULL,
+ &specific_scrap);
+ if (err == noErr)
+ err = mac_clear_selection (&cur_scrap);
+ if (err == noErr)
+ for (rest = Vselection_converter_alist; CONSP (rest);
+ rest = XCDR (rest))
+ {
+ if (! (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest)))))
+ continue;
+ flavor_type = get_flavor_type_from_symbol (XCAR (XCAR (rest)),
+ specific_scrap);
+ if (flavor_type == 0)
+ continue;
+ err = copy_scrap_flavor_data (specific_scrap, cur_scrap,
+ flavor_type);
+ if (err == noErr)
+ data_exists_p = 1;
+ }
+ if (!data_exists_p)
+ err = eventNotHandledErr;
+ else
+ err = mac_store_service_event (event);
+ }
+ break;
+ }
+
+ if (err != noErr)
+ err = eventNotHandledErr;
+ return err;
+}
+
+static OSStatus
+install_service_handler ()
+{
+ static const EventTypeSpec specs[] =
+ {{kEventClassService, kEventServiceGetTypes},
+ {kEventClassService, kEventServiceCopy},
+ {kEventClassService, kEventServicePaste},
+ {kEventClassService, kEventServicePerform}};
+
+ return InstallApplicationEventHandler (NewEventHandlerUPP
+ (mac_handle_service_event),
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+}
+#endif /* MAC_OSX */
+
+\f
+/***********************************************************************
+ Initialization
+ ***********************************************************************/
+
+void
+mac_toolbox_initialize ()
+{
+ any_help_event_p = 0;
+
+ init_menu_bar ();
+
+#ifdef MAC_OSX
+ init_apple_event_handler ();
+#endif
+#if USE_MAC_TSM
+ init_tsm ();
+#endif
+}
+
+/* arch-tag: 71a597a8-6e9f-47b0-8b89-5a5ae3e16516
+ (do not change this comment) */
doc: /* Return a Lisp object read using the minibuffer, unevaluated.
Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS
is a string to insert in the minibuffer before reading.
-\(INITIAL-CONTENTS can also be a cons of a string and an integer. Such
-arguments are used as in `read-from-minibuffer'.) */)
+\(INITIAL-CONTENTS can also be a cons of a string and an integer.
+Such arguments are used as in `read-from-minibuffer'.) */)
(prompt, initial_contents)
Lisp_Object prompt, initial_contents;
{
doc: /* Return value of Lisp expression read using the minibuffer.
Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS
is a string to insert in the minibuffer before reading.
-\(INITIAL-CONTENTS can also be a cons of a string and an integer. Such
-arguments are used as in `read-from-minibuffer'.) */)
+\(INITIAL-CONTENTS can also be a cons of a string and an integer.
+Such arguments are used as in `read-from-minibuffer'.) */)
(prompt, initial_contents)
Lisp_Object prompt, initial_contents;
{
QUIT;
+ /* See similar code in print_preprocess. */
+ if (print_depth >= PRINT_CIRCLE)
+ error ("Apparently circular structure being printed");
+
/* Detect circularities and truncate them. */
if (STRINGP (obj) || CONSP (obj) || VECTORP (obj)
|| COMPILEDP (obj) || CHAR_TABLE_P (obj)
print_depth++;
- /* See similar code in print_preprocess. */
- if (print_depth > PRINT_CIRCLE)
- error ("Apparently circular structure being printed");
#ifdef MAX_PRINT_CHARS
if (max_print && print_chars > max_print)
{
p->raw_status_new = 0;
p->status = Qrun;
p->mark = Fmake_marker ();
+ p->kill_without_query = Qnil;
#ifdef ADAPTIVE_READ_BUFFERING
p->adaptive_read_buffering = Qnil;
int inchannel, outchannel;
pid_t pid;
int sv[2];
+#if !defined (WINDOWSNT) && defined (FD_CLOEXEC)
+ int wait_child_setup[2];
+#endif
#ifdef POSIX_SIGNALS
sigset_t procmask;
sigset_t blocked;
#endif
if (forkin < 0)
report_file_error ("Opening pty", Qnil);
-#if defined (RTU) || defined (UNIPLUS) || defined (DONT_REOPEN_PTY)
- /* In the case that vfork is defined as fork, the parent process
- (Emacs) may send some data before the child process completes
- tty options setup. So we setup tty before forking. */
- child_setup_tty (forkout);
-#endif /* RTU or UNIPLUS or DONT_REOPEN_PTY */
#else
forkin = forkout = -1;
#endif /* not USG, or USG_SUBTTY_WORKS */
}
#endif /* not SKTPAIR */
+#if !defined (WINDOWSNT) && defined (FD_CLOEXEC)
+ {
+ int tem;
+
+ tem = pipe (wait_child_setup);
+ if (tem < 0)
+ report_file_error ("Creating pipe", Qnil);
+ tem = fcntl (wait_child_setup[1], F_GETFD, 0);
+ if (tem >= 0)
+ tem = fcntl (wait_child_setup[1], F_SETFD, tem | FD_CLOEXEC);
+ if (tem < 0)
+ {
+ emacs_close (wait_child_setup[0]);
+ emacs_close (wait_child_setup[1]);
+ report_file_error ("Setting file descriptor flags", Qnil);
+ }
+ }
+#endif
+
#if 0
/* Replaced by close_process_descs */
set_exclusive_use (inchannel);
#endif /* SIGCHLD */
#endif /* !POSIX_SIGNALS */
-#if !defined (RTU) && !defined (UNIPLUS) && !defined (DONT_REOPEN_PTY)
if (pty_flag)
child_setup_tty (xforkout);
-#endif /* not RTU and not UNIPLUS and not DONT_REOPEN_PTY */
#ifdef WINDOWSNT
pid = child_setup (xforkin, xforkout, xforkout,
new_argv, 1, current_dir);
#else /* not WINDOWSNT */
+#ifdef FD_CLOEXEC
+ emacs_close (wait_child_setup[0]);
+#endif
child_setup (xforkin, xforkout, xforkout,
new_argv, 1, current_dir);
#endif /* not WINDOWSNT */
else
#endif
XPROCESS (process)->tty_name = Qnil;
+
+#if !defined (WINDOWSNT) && defined (FD_CLOEXEC)
+ /* Wait for child_setup to complete in case that vfork is
+ actually defined as fork. The descriptor wait_child_setup[1]
+ of a pipe is closed at the child side either by close-on-exec
+ on successful execvp or the _exit call in child_setup. */
+ {
+ char dummy;
+
+ emacs_close (wait_child_setup[1]);
+ emacs_read (wait_child_setup[0], &dummy, 1);
+ emacs_close (wait_child_setup[0]);
+ }
+#endif
}
/* Restore the signal state whether vfork succeeded or not.
#endif
Atemp = input_wait_mask;
-#if 0
- /* On Mac OS X 10.0, the SELECT system call always says input is
- present (for reading) at stdin, even when none is. This
- causes the call to SELECT below to return 1 and
- status_notify not to be called. As a result output of
- subprocesses are incorrectly discarded.
- */
- FD_CLR (0, &Atemp);
-#endif
IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask);
EMACS_SET_SECS_USECS (timeout, 0, 0);
#endif
#ifndef BASE_PURESIZE
-#define BASE_PURESIZE (1130000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
+#define BASE_PURESIZE (1140000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
#endif
/* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */
being larger than MAX_BUF_SIZE, then flag memory exhausted. */
#if __BOUNDED_POINTERS__
# define SET_HIGH_BOUND(P) (__ptrhigh (P) = __ptrlow (P) + bufp->allocated)
-# define MOVE_BUFFER_POINTER(P) \
- (__ptrlow (P) += incr, SET_HIGH_BOUND (P), __ptrvalue (P) += incr)
+# define MOVE_BUFFER_POINTER(P) \
+ (__ptrlow (P) = new_buffer + (__ptrlow (P) - old_buffer), \
+ SET_HIGH_BOUND (P), \
+ __ptrvalue (P) = new_buffer + (__ptrvalue (P) - old_buffer))
# define ELSE_EXTEND_BUFFER_HIGH_BOUND \
else \
{ \
SET_HIGH_BOUND (pending_exact); \
}
#else
-# define MOVE_BUFFER_POINTER(P) (P) += incr
+# define MOVE_BUFFER_POINTER(P) ((P) = new_buffer + ((P) - old_buffer))
# define ELSE_EXTEND_BUFFER_HIGH_BOUND
#endif
#define EXTEND_BUFFER() \
do { \
- re_char *old_buffer = bufp->buffer; \
+ unsigned char *old_buffer = bufp->buffer; \
if (bufp->allocated == MAX_BUF_SIZE) \
return REG_ESIZE; \
bufp->allocated <<= 1; \
/* If the buffer moved, move all the pointers into it. */ \
if (old_buffer != bufp->buffer) \
{ \
- int incr = bufp->buffer - old_buffer; \
+ unsigned char *new_buffer = bufp->buffer; \
MOVE_BUFFER_POINTER (b); \
MOVE_BUFFER_POINTER (begalt); \
if (fixup_alt_jump) \
/* Indicate that we are compiling for Mac OS X. */
#define C_SWITCH_SYSTEM -fpascal-strings -DMAC_OSX
+#ifdef HAVE_CARBON
+
+#ifdef HAVE_AVAILABILITYMACROS_H
+#include <AvailabilityMacros.h>
+#endif
+
+/* Whether to use the Image I/O framework for reading images. */
+#ifndef USE_MAC_IMAGE_IO
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1040 || MAC_OS_X_VERSION_MIN_REQUIRED < 1020)
+#define USE_MAC_IMAGE_IO 1
+#endif
+#endif
+
+/* If the Image I/O framework is not used, fall back on QuickTime. */
+#if USE_MAC_IMAGE_IO
+#define LIBS_IMAGE
+#else
+#define LIBS_IMAGE -framework QuickTime
+#endif
+
+#endif /* HAVE_CARBON */
+
/* Link in the Carbon lib. */
#ifdef HAVE_CARBON
-#define LIBS_CARBON -framework Carbon -framework QuickTime
+#define LIBS_CARBON -framework Carbon LIBS_IMAGE
#else
#define LIBS_CARBON
#endif
/* The following solves the problem that Emacs hangs when evaluating
(make-comint "test0" "/nodir/nofile" nil "") when /nodir/nofile
- does not exist. */
+ does not exist. Also, setsid is not allowed in the vfork child's
+ context as of Darwin 9/Mac OS X 10.5. */
#undef HAVE_WORKING_VFORK
#define vfork fork
cp->buf.translate = (! NILP (translate) ? translate : make_number (0));
cp->posix = posix;
cp->buf.multibyte = multibyte;
- cp->whitespace_regexp = Vsearch_spaces_regexp;
+ if (STRINGP (Vsearch_spaces_regexp))
+ cp->whitespace_regexp = Vsearch_spaces_regexp;
+ else
+ cp->whitespace_regexp = Qnil;
+
/* rms: I think BLOCK_INPUT is not needed here any more,
because regex.c defines malloc to call xmalloc.
Using BLOCK_INPUT here means the debugger won't run if an error occurs.
old = re_set_syntax (RE_SYNTAX_EMACS
| (posix ? 0 : RE_NO_POSIX_BACKTRACKING));
- re_set_whitespace_regexp (NILP (Vsearch_spaces_regexp) ? NULL
- : SDATA (Vsearch_spaces_regexp));
+ if (STRINGP (Vsearch_spaces_regexp))
+ re_set_whitespace_regexp (SDATA (Vsearch_spaces_regexp));
+ else
+ re_set_whitespace_regexp (NULL);
val = (char *) re_compile_pattern ((char *)raw_pattern,
raw_pattern_size, &cp->buf);
extern void init_signals P_ ((void));
-#ifdef HAVE_GTK_AND_PTHREAD
+#if defined (HAVE_GTK_AND_PTHREAD) || (defined (HAVE_CARBON) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1020)
#include <pthread.h>
+/* If defined, asynchronous signals delivered to a non-main thread are
+ forwarded to the main thread. */
+#define FORWARD_SIGNAL_TO_MAIN_THREAD
+#endif
+
+#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
extern pthread_t main_thread;
#endif
char *strsignal ();
#endif
-#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
#define SIGNAL_THREAD_CHECK(signo) \
do { \
if (!pthread_equal (pthread_self (), main_thread)) \
} \
} while (0)
-#else /* not HAVE_GTK_AND_PTHREAD */
+#else /* not FORWARD_SIGNAL_TO_MAIN_THREAD */
#define SIGNAL_THREAD_CHECK(signo)
-#endif /* not HAVE_GTK_AND_PTHREAD */
+#endif /* not FORWARD_SIGNAL_TO_MAIN_THREAD */
/* arch-tag: 4580e86a-340d-4574-9e11-a742b6e1a152
(do not change this comment) */
defsubr (&Stty_no_underline);
fullscreen_hook = NULL;
+#ifndef WINDOWSNT
+ default_orig_pair = NULL;
+ default_set_foreground = NULL;
+ default_set_background = NULL;
+#endif
}
/* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
markers). If OBJECT is a string, START and END are 0-based indices into it.
Return t if any property was actually removed, nil otherwise.
-Use set-text-properties if you want to remove all text properties. */)
+Use `set-text-properties' if you want to remove all text properties. */)
(start, end, properties, object)
Lisp_Object start, end, properties, object;
{
If a character in a buffer has PROPERTY, new text inserted adjacent to
the character doesn't inherit PROPERTY if NONSTICKINESS is non-nil,
-inherits it if NONSTICKINESS is nil. The front-sticky and
-rear-nonsticky properties of the character overrides NONSTICKINESS. */);
+inherits it if NONSTICKINESS is nil. The `front-sticky' and
+`rear-nonsticky' properties of the character override NONSTICKINESS. */);
/* Text property `syntax-table' should be nonsticky by default. */
Vtext_property_default_nonsticky
= Fcons (Fcons (intern ("syntax-table"), Qt), Qnil);
#else /* not SUNOS4_SHARED_LIBRARIES */
rel = erel = 0;
#endif /* not SUNOS4_SHARED_LIBRARIES */
-#ifdef sparc
+#ifdef __sparc__
#define REL_INFO_TYPE struct reloc_info_sparc
#else
#define REL_INFO_TYPE struct relocation_info
-#endif /* sparc */
+#endif /* __sparc__ */
#define REL_TARGET_ADDRESS(r) (((REL_INFO_TYPE *)(r))->r_address)
#endif /* SUNOS4 */
#if defined (__FreeBSD__) || defined (__NetBSD__)
}
#else /* not NO_LIM_DATA */
+#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_AS)
+static void
+get_lim_data ()
+{
+ struct rlimit rlimit;
+
+ getrlimit (RLIMIT_AS, &rlimit);
+ if (rlimit.rlim_cur == RLIM_INFINITY)
+ lim_data = -1;
+ else
+ lim_data = rlimit.rlim_cur;
+}
+
+#else /* not HAVE_GETRLIMIT */
+
#ifdef USG
static void
#endif /* BSD4_2 */
#endif /* not WINDOWSNT */
#endif /* not USG */
+#endif /* not HAVE_GETRLIMIT */
#endif /* not NO_LIM_DATA */
\f
/* Verify amount of memory available, complaining if we're near the end. */
#endif
extern POINTER (*__morecore) ();
-
register POINTER cp;
unsigned long five_percent;
unsigned long data_size;
enum warnlevel new_warnlevel;
-#ifdef HAVE_GETRLIMIT
- struct rlimit rlimit;
-
- getrlimit (RLIMIT_AS, &rlimit);
-
- if (RLIM_INFINITY == rlimit.rlim_max)
- return;
-
- /* This is a nonsensical case, but it happens -- rms. */
- if (rlimit.rlim_cur > rlimit.rlim_max)
- return;
-
- five_percent = rlimit.rlim_max / 20;
- data_size = rlimit.rlim_cur;
-
-#else /* not HAVE_GETRLIMIT */
-
if (lim_data == 0)
get_lim_data ();
five_percent = lim_data / 20;
cp = (char *) (*__morecore) (0);
data_size = (char *) cp - (char *) data_space_start;
-#endif /* not HAVE_GETRLIMIT */
-
if (!warn_function)
return;
/* What level of warning does current memory usage demand? */
- if (data_size > five_percent * 19)
- new_warnlevel = warned_95;
- else if (data_size > five_percent * 17)
- new_warnlevel = warned_85;
- else if (data_size > five_percent * 15)
- new_warnlevel = warned_75;
- else
- new_warnlevel = not_warned;
+ new_warnlevel
+ = (data_size > five_percent * 19) ? warned_95
+ : (data_size > five_percent * 17) ? warned_85
+ : (data_size > five_percent * 15) ? warned_75
+ : not_warned;
/* If we have gone up a level, give the appropriate warning. */
if (new_warnlevel > warnlevel || new_warnlevel == warned_95)
extern Lisp_Object Vw32_downcase_file_names;
extern Lisp_Object Vw32_generate_fake_inodes;
extern Lisp_Object Vw32_get_true_file_attributes;
+/* Defined in process.c for its own purpose. */
+extern Lisp_Object Qlocal;
+
extern int w32_num_mouse_buttons;
\f
struct direct *
readdir (DIR *dirp)
{
+ int downcase = !NILP (Vw32_downcase_file_names);
+
if (wnet_enum_handle != INVALID_HANDLE_VALUE)
{
if (!read_unc_volume (wnet_enum_handle,
dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
dir_static.d_namlen - dir_static.d_namlen % 4;
- dir_static.d_namlen = strlen (dir_find_data.cFileName);
- strcpy (dir_static.d_name, dir_find_data.cFileName);
+ /* If the file name in cFileName[] includes `?' characters, it means
+ the original file name used characters that cannot be represented
+ by the current ANSI codepage. To avoid total lossage, retrieve
+ the short 8+3 alias of the long file name. */
+ if (_mbspbrk (dir_find_data.cFileName, "?"))
+ {
+ strcpy (dir_static.d_name, dir_find_data.cAlternateFileName);
+ /* 8+3 aliases are returned in all caps, which could break
+ various alists that look at filenames' extensions. */
+ downcase = 1;
+ }
+ else
+ strcpy (dir_static.d_name, dir_find_data.cFileName);
+ dir_static.d_namlen = strlen (dir_static.d_name);
if (dir_is_fat)
_strlwr (dir_static.d_name);
- else if (!NILP (Vw32_downcase_file_names))
+ else if (downcase)
{
register char *p;
for (p = dir_static.d_name; *p; p++)
stat (const char * path, struct stat * buf)
{
char *name, *r;
+ char drive_root[4];
+ UINT devtype;
WIN32_FIND_DATA wfd;
HANDLE fh;
DWORD fake_inode;
}
}
- if (!NILP (Vw32_get_true_file_attributes)
+ /* GetDriveType needs the root directory of NAME's drive. */
+ if (!(strlen (name) >= 2 && IS_DEVICE_SEP (name[1])))
+ devtype = GetDriveType (NULL); /* use root of current diectory */
+ else
+ {
+ strncpy (drive_root, name, 3);
+ drive_root[3] = '\0';
+ devtype = GetDriveType (drive_root);
+ }
+
+ if (!(NILP (Vw32_get_true_file_attributes)
+ || (EQ (Vw32_get_true_file_attributes, Qlocal) &&
+ devtype != DRIVE_FIXED && devtype != DRIVE_RAMDISK))
/* No access rights required to get info. */
&& (fh = CreateFile (name, 0, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL))
DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
Sw32_define_rgb_color, 4, 4, 0,
- doc: /* Convert RGB numbers to a windows color reference and associate with NAME.
+ doc: /* Convert RGB numbers to a Windows color reference and associate with NAME.
This adds or updates a named color to `w32-color-map', making it
available for use. The original entry's RGB ref is returned, or nil
if the entry is new. */)
#include "lisp.h"
#include "keyboard.h"
#include "frame.h"
+#include "dispextern.h"
#include "blockinput.h"
#include "termhooks.h"
#include "w32heap.h"
/* from keyboard.c */
extern void reinvoke_input_signal (void);
-/* from dispnew.c */
-extern int change_frame_size (FRAME_PTR, int, int, int, int);
-
/* from w32console.c */
extern int w32_use_full_screen_buffer;
{
FRAME_PTR f = get_frame ();
- change_frame_size (f, event->dwSize.Y, event->dwSize.X, 0, 1);
+ change_frame_size (f, event->dwSize.Y, event->dwSize.X, 0, 1, 0);
SET_FRAME_GARBAGED (f);
}
change_frame_size (f,
1 + info.srWindow.Bottom - info.srWindow.Top,
1 + info.srWindow.Right - info.srWindow.Left,
- 0, 0);
+ 0, 0, 0);
}
int
if (NILP (position))
{
discard_menu_items ();
+ FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
UNGCPRO;
return Qnil;
}
if (current_popup_menu)
{
discard_menu_items ();
+ FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
UNGCPRO;
return Qnil;
}
UNBLOCK_INPUT;
discard_menu_items ();
+ FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
#endif /* HAVE_MENUS */
UNBLOCK_INPUT;
discard_menu_items ();
+ FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
if (error_name) error (error_name);
return selection;
/* Clean up extraneous mouse events which might have been generated
during the call. */
discard_mouse_events ();
+ FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
/* Free the widget_value objects we used to specify the contents. */
free_menubar_widget_value_tree (first_wv);
exactly, at the expense of slower operation. Since true hard links
are supported on NTFS volumes, this is only relevant on NT. */
Lisp_Object Vw32_get_true_file_attributes;
+extern Lisp_Object Qlocal;
Lisp_Object Qhigh, Qlow;
#endif
DEFVAR_LISP ("w32-get-true-file-attributes", &Vw32_get_true_file_attributes,
- doc: /* Non-nil means determine accurate link count in `file-attributes'.
-Note that this option is only useful for files on NTFS volumes, where hard links
-are supported. Moreover, it slows down `file-attributes' noticeably. */);
- Vw32_get_true_file_attributes = Qt;
+ doc: /* If non-nil, determine accurate link count and file type in `file-attributes'.
+This option is mostly useful for files on NTFS volumes, where
+hard links are supported. The default value `local' means only do
+this for files on local fixed drives. Any other non-nil value means do
+this even on remote and removable drives where the performance impact
+may be noticeable even on modern hardware. */);
+ Vw32_get_true_file_attributes = Qlocal;
staticpro (&Vw32_valid_locale_ids);
staticpro (&Vw32_valid_codepages);
SetBkMode (s->hdc, TRANSPARENT);
SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
- if (s->font && s->font->hfont)
- old_font = SelectObject (s->hdc, s->font->hfont);
-
/* Draw a rectangle for the composition if the font for the very
first character of the composition could not be loaded. */
if (s->font_not_found_p)
}
else
{
+ if (s->font && s->font->hfont)
+ old_font = SelectObject (s->hdc, s->font->hfont);
+
+ /* Because of the way Emacs encodes composite glyphs, the font_type
+ may not be set up yet. Always use unicode for composite glyphs. */
+ s->first_glyph->font_type = UNICODE_FONT;
+
for (i = 0; i < s->nchars; i++, ++s->gidx)
{
w32_text_out (s, x + s->cmp->offsets[s->gidx * 2],
s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
s->char2b + i, 1);
}
- }
- if (s->font && s->font->hfont)
- SelectObject (s->hdc, old_font);
+ if (s->font && s->font->hfont)
+ SelectObject (s->hdc, old_font);
+ }
}
text, or we can't tell because W's current matrix is not up to
date. */
-static struct glyph *
+#ifndef HAVE_CARBON
+static
+#endif
+struct glyph *
x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
struct window *w;
int x, y;
/* If we're at the end of the buffer, record that we have
processed the overlay strings there already, so that
next_element_from_buffer doesn't try it again. */
- if (IT_CHARPOS (*it) >= it->end_charpos)
+ if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
it->overlay_strings_at_end_processed_p = 1;
/* If we have to display `...' for invisible text, set
out:
+ /* On text terminals, we may stop at the end of a line in the middle
+ of a multi-character glyph. If the glyph itself is continued,
+ i.e. it is actually displayed on the next line, don't treat this
+ stopping point as valid; move to the next line instead (unless
+ that brings us offscreen). */
+ if (!FRAME_WINDOW_P (it->f)
+ && op & MOVE_TO_POS
+ && IT_CHARPOS (*it) == to_charpos
+ && it->what == IT_CHARACTER
+ && it->nglyphs > 1
+ && !it->truncate_lines_p
+ && it->current_x == it->last_visible_x - 1
+ && it->c != '\n'
+ && it->c != '\t'
+ && it->vpos < XFASTINT (it->w->window_end_vpos))
+ {
+ it->continuation_lines_width += it->current_x;
+ it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
+ it->current_y += it->max_ascent + it->max_descent;
+ ++it->vpos;
+ last_height = it->max_ascent + it->max_descent;
+ last_max_ascent = it->max_ascent;
+ }
+
TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
}
struct frame *f;
int save_match_data;
{
-#ifdef USE_GTK
+#if defined (USE_GTK) || USE_MAC_TOOLBAR
int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
#else
int do_update = WINDOWP (f->tool_bar_window)
struct it it;
struct glyph_row *row;
-#ifdef USE_GTK
+#if defined (USE_GTK) || USE_MAC_TOOLBAR
if (FRAME_EXTERNAL_TOOL_BAR (f))
update_frame_tool_bar (f);
return 0;
{
/* We set this later on if we have to adjust point. */
int new_vpos = -1;
- int val;
w->force_start = Qnil;
w->vscroll = 0;
/* Redisplay, then check if cursor has been set during the
redisplay. Give up if new fonts were loaded. */
- val = try_window (window, startp, 1);
- if (!val)
+ /* We used to issue a CHECK_MARGINS argument to try_window here,
+ but this causes scrolling to fail when point begins inside
+ the scroll margin (bug#148) -- cyd */
+ if (!try_window (window, startp, 0))
{
w->force_start = Qt;
clear_glyph_matrix (w->desired_matrix);
goto need_larger_matrices;
}
- /* Point was outside the scroll margins. */
- if (val < 0)
- new_vpos = window_box_height (w) / 2;
if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
{
display_menu_bar (w);
#ifdef HAVE_WINDOW_SYSTEM
-#ifdef USE_GTK
+#if defined (USE_GTK) || USE_MAC_TOOLBAR
redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
#else
redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
seems to give wrong results. We don't want to recenter
when the last line is partly visible, we want to allow
that case to be handled in the usual way. */
- || (w->cursor.y + 1) > it.last_visible_y)
+ || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
{
w->cursor.vpos = -1;
clear_glyph_matrix (w->desired_matrix);
in 20.x as well, and I think it's too risky to install
so near the release of 21.1. 2001-09-25 gerd. */
-static int
+#ifndef HAVE_CARBON
+static
+#endif
+int
fast_find_position (w, charpos, hpos, vpos, x, y, stop)
struct window *w;
int charpos;
doc: /* *Scroll up to this many lines, to bring point back on screen.
If point moves off-screen, redisplay will scroll by up to
`scroll-conservatively' lines in order to bring point just barely
-onto the screen again. If that cannot be done, then redisplay
+onto the screen again. If that cannot be done, then redisplay
recenters point as usual.
A value of zero means always recenter point if it moves off screen. */);
FACE is a face name--a symbol.
The return value is a list of strings, suitable as arguments to
-set-face-font.
+`set-face-font'.
Fonts Emacs can't use may or may not be excluded
even if they match PATTERN and FACE.
If FRAME is t, copy the global face definition of FROM.
Otherwise, copy the frame-local definition of FROM on FRAME.
If NEW-FRAME is a frame, copy that data into the frame-local
-definition of TO on NEW-FRAME. If NEW-FRAME is nil.
+definition of TO on NEW-FRAME. If NEW-FRAME is nil,
FRAME controls where the data is copied to.
The value is TO. */)
/* Activate the first menu. */
GList *children = gtk_container_get_children (GTK_CONTAINER (menubar));
- gtk_menu_shell_select_item (GTK_MENU_SHELL (menubar),
- GTK_WIDGET (children->data));
-
- popup_activated_flag = 1;
- g_list_free (children);
+ if (children)
+ {
+ g_signal_emit_by_name (children->data, "activate_item");
+ popup_activated_flag = 1;
+ g_list_free (children);
+ }
}
UNBLOCK_INPUT;
with the high 16 bits from the car and the lower 16 bit from the cdr. That
number is then used as a window id.
If DEST is a frame the event is sent to the outer window of that frame.
-Nil means the currently selected frame.
+A value of nil means the currently selected frame.
If DEST is the string "PointerWindow" the event is sent to the window that
contains the pointer. If DEST is the string "InputFocus" the event is
sent to the window that has the input focus.
if (
#ifdef USE_GTK
! popup_activated ()
+ /* Gtk+ menus only react to the first three buttons. */
+ && event.xbutton.button < 3
&&
#endif
f && event.type == ButtonPress
tail->next = tail->next->next;
}
-#ifndef USE_X_TOOLKIT /* I'm told Xt does this itself. */
+#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
#ifndef AIX /* On AIX, XCloseDisplay calls this. */
+ /* Xt and GTK does this themselves. */
XrmDestroyDatabase (dpyinfo->xrdb);
#endif
#endif